import React from "react";

import PageContent from '../../PageContent'

import { ajax ,showResultMessage,fetchData,batchAjax,inArray,randomString,isNull, isNotNull,isEmpty,setStoreItem,getStoreItem} from '../../common';

import {Row,Col,List,Divider,Select,message,Spin,Collapse } from 'antd';

import brace from 'brace';

import AceEditor from 'react-ace';

import 'brace/mode/java';

import 'brace/theme/github';

import {UIDataTableView} from '../../uicomponents/UIDataComponentView';

import UIFormView from '../../uicomponents/UIFormView';

import UIActionBar from '../../uicomponents/UIActionBar';

import UICardTabs from '../../uicomponents/UICardTabs';

import UIView from '../../uicomponents/UIView';

import UIForm from '../../uicomponents/UIForm';

import UIIcon from '../../uicomponents/UIIcon';

import UIWizard from '../../uicomponents/UIWizard';

import UITabsView from '../../uicomponents/UITabsView';

import StartJobModla from '../../uicomponents/StartJobModla';

import ProductModelDomainSelect from './ProductModelDomainSelect';

import ProductDatabaseSelect from './ProductDatabaseSelect';

import ProductModelPackageSelect from './ProductModelPackageSelect';

import ProductModelObjectSelect from './ProductModelObjectSelect';

const Option = Select.Option;


/** 
 * 产品数据模型管理
*/

export default class ProductModelObjectManageApp extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            modelDomain: null,
        }
    }

    state = {
        activeTabKey : '',
    }


    onSelectModelDomain = (modelDomain) => {
        this.setState({ modelDomain: modelDomain });
    }

    onTabChange = (tabName) => {
        this.setState({activeTabKey : tabName});
    }

    render() {

        const { modelDomain } = this.state;

        /**路由设置 */
        const pageContentMap = {
            '/': {
                text: '模型对象列表',
                icon: '',
                getComponent: (owner, props) => {
                    return (<ProductModelObjectTabsPanel activeTabKey={this.state.activeTabKey} onTabChange={this.onTabChange} onSelectModelDomain={owner.onSelectModelDomain} {...props} key="modelObjectList" />);
                }
            },
            '/importDataTable': {
                text: '导入数据表对象',
                icon: 'table',
                getComponent: (owner, props) => {
                    return (<ImportDataTablePanel modelDomain={modelDomain} {...props} key="importDataTable" />);
                }
            },
            '/editTableObject': {
                text: '编辑数据表对象',
                icon: 'table',
                getComponent: (owner, props) => {
                    return (<DataTableObjectEditTabsPanel modelDomain={modelDomain} {...props} key="editDataTable" />);
                }
            },
            '/editDaoObject': {
                text: '编辑DAO对象',
                icon: 'cog',
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectEditTabsPanel modelDomain={modelDomain} {...props} key="editDao" />);
                }
            },
            '/editDtoObject': {
                text: '编辑DTO对象',
                icon: 'cube',
                getComponent: (owner, props) => {
                    return (<ProductDtoObjectEditTabsPanel modelDomain={modelDomain} {...props} key="editDto" />);
                }
            },
            '/editEnumObject': {
                text: '编辑枚举对象',
                icon: 'th-list',
                getComponent: (owner, props) => {
                    return (<ProductEnumObjectEditTabsPanel modelDomain={modelDomain} {...props} key="editEnum" />);
                }
            },
            '/editServiceObject': {
                text: '编辑服务对象',
                icon: 'cogs',
                getComponent: (owner, props) => {
                    return (<ProductServiceObjectEditTabsPanel modelDomain={modelDomain} {...props} key="editService" />);
                }
            },
        }

        return (
            <PageContent {...this.props} pageInstance={this} contentMap={pageContentMap} />
        );
    }
}


/** 
* 模型对象Tabs
*/
class ProductModelObjectTabsPanel extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            modelDomain: null,
        }
    }

    componentDidMount() {
        if (getStoreItem('lastSelectModelDomainId')) {
            this.onSelectModelDomain(getStoreItem('lastSelectModelDomainId') );
        }
    }

    onSelectModelDomain = (modelDomainId) => {
        
        ajax('PRODUCT/MODEL/productModelDomain/getModelDomainById', { id: modelDomainId }, (data) => {
            
            this.setState({ modelDomain: data });
            setTimeout(() => {
                this.loadDomainData(data);
                if (this.props.onSelectModelDomain !== null) {
                    this.props.onSelectModelDomain(data);
                }
            });
        });
    }

    loadDomainData = (modelDomain) => {
        const modelDomainId = modelDomain.id;
        
        if (this.dataTableListRef !== undefined && this.dataTableListRef !== null) {
            this.dataTableListRef.loadDomainData(modelDomainId);
        }
        if (this.daoObjectListRef !== undefined && this.daoObjectListRef !== null) {
            this.daoObjectListRef.loadDomainData(modelDomainId);
        }
        if (this.dtoObjectListRef !== undefined && this.dtoObjectListRef !== null) {
            this.dtoObjectListRef.loadDomainData(modelDomainId);
        }
        if (this.enumObjectListRef !== undefined && this.enumObjectListRef !== null) {
            this.enumObjectListRef.loadDomainData(modelDomainId);
        }
        if (this.serviceObjectListRef !== undefined && this.serviceObjectListRef
             !== null) {
            this.serviceObjectListRef.loadDomainData(modelDomainId);
        }

    }

    onTabChange = (tabName) => {
        const { modelDomain } = this.state;
        const modelDomainId = modelDomain.id;
        switch (tabName) {
            case 'dataTable':
                this.dataTableListRef.loadDomainData(modelDomainId);
                break;
            case 'daoObject':
                this.daoObjectListRef.loadDomainData(modelDomainId);
                break;
            case 'dtoObject':
                this.dtoObjectListRef.loadDomainData(modelDomainId);
                break;
            case 'enumObject':
                this.enumObjectListRef.loadDomainData(modelDomainId);
                break;
            case 'serviceObject':
                this.serviceObjectListRef.loadDomainData(modelDomainId);
                break;
        }

        if(this.props.onTabChange !== undefined){
            this.props.onTabChange(tabName);
        }
    }

    render() {
        const { modelDomain } = this.state;

        const pageHistory = this.props.history;

        const tabPanelContentMap = {
            '/dataTable': {
                getComponent: (owner, props) => {
                    return <ProductDataTableListPanel {...props} pageHistory={pageHistory} ref={(inst) => this.dataTableListRef = inst}/>;
                }
            },
            '/daoObject': {
                getComponent: (owner, props) => {
                    return <ProductDaoObjectListPanel {...props} pageHistory={pageHistory} ref={(inst) => this.daoObjectListRef = inst}/>;
                }
            },
            '/dtoObject': {
                getComponent: (owner, props) => {
                    return <ProductDtoObjectListPanel {...props} pageHistory={pageHistory} ref={(inst) => this.dtoObjectListRef = inst}/>;
                }
            },
            '/enumObject': {
                getComponent: (owner, props) => {
                    return <ProductEnumObjectListPanel {...props} pageHistory={pageHistory} ref={(inst) => this.enumObjectListRef = inst}/>;
                }
            },
            '/serviceObject': {
                getComponent: (owner, props) => {
                    return <ProductServiceObjectListPanel {...props} pageHistory={pageHistory} ref={(inst) => this.serviceObjectListRef = inst}/>;
                }
            },
        };

        const dataModelTabsProps = {
            tabConfigId: 'dataModelTab',
            activeTabKey : this.props.activeTabKey,
            title: (modelDomain !== null ? <span><UIIcon icon='cubes'></UIIcon>{'[' + modelDomain.domainName + ']模型对象列表'}</span> : <span><UIIcon icon="question"></UIIcon>{'请选择模型域'}</span>),
            extra: <ProductModelDomainSelect onSelectModelDomain={this.onSelectModelDomain}></ProductModelDomainSelect>,
            onTabChange: this.onTabChange,
            tabContentMap: tabPanelContentMap,
        }

        return (
            <UICardTabs {...dataModelTabsProps}>

            </UICardTabs>
        );
    }
}

/**
 * 模型对象表单
 */
const WarpModelObjectFormPanel = (props) => {
    class WarpModelObjectFormPanel extends React.Component {

        setModelObject = (modelObject) => {
            this.modelObjectFormRef.setFormData(modelObject);
        }

        actionHandler = (actionEvent) => {

            return {
                doSave: () => {
                    this.modelObjectFormRef.getFormData((formData) => {

                        ajax('PRODUCT/MODEL/productModelObject/saveModelObject', formData, (data) => {
                            this.modelObjectFormRef.setFormData(data);
                            showResultMessage({
                                success: true,
                                message: 'message.saveSuccess',
                            });
                        });
                    });
                }
            };
        }

        render() {

            const objectFormProps = {
                formConfigId: props.formConfigId,
                wrappedComponentRef: (inst) => this.modelObjectFormRef = inst,
                actionGroupId: 'saveActionGroup',
                actionHandler: this.actionHandler,
            }

            return (
                <UIForm {...objectFormProps} {...this.props}>

                </UIForm>
            );
        }
    }

    return WarpModelObjectFormPanel;
}

/**
 * 模型属性列表
 */
const WarpModelPropertyListTabPanel = (props) => {

    class ModelPropertyListTabPanel extends React.Component {

        constructor(props) {
            super(props);
            this.state = {
                formTitle: '',
            }
        }
    
        setModelObject = (modelObject) => {
            this.modelObject = modelObject;
            this.propertyListRef.loadData({ id: modelObject.id });
        }
    
        actionHandler = (actionEvent) => {
    
            const { propertyListRef, propertyFormRef, selectPropertyIds, modelObject } = this;
    
            return {
                refresh: () => {
                    propertyListRef.loadData({ id: modelObject.id });
                },
                addNew: () => {
                    this.setState({ formTitle: '新增对象属性' });
                    setTimeout(() => {
                        propertyFormRef.openModal();
                    });
                },
                doEdit: () => {
                    this.setState({ formTitle: '编辑对象属性' });
                    setTimeout(() => {
                        propertyFormRef.openModal(() => {
                            propertyFormRef.setFormData(actionEvent.params);
                        });
                    });
                },
                doSave: () => {
    
                    propertyFormRef.getFormData((formData) => {
                        formData.objectId = modelObject.id;
    
                        ajax('PRODUCT/MODEL/productModelObject/saveModelProperty', formData, (data) => {
                            propertyFormRef.closeModal();
                            propertyListRef.loadData({ id: modelObject.id });
                            showResultMessage({
                                success: true,
                                message: 'message.saveSuccess',
                            });
                        })
                    });
                },
                doDelete: () => {

                    const selectModelPropertis = isNull(actionEvent.params) === false ? [actionEvent.params] : propertyListRef.getSelectedDatas();
    
                    const ids = [];

                    selectModelPropertis.map(modelProperty => {
    
                        const relatedData = fetchData('PRODUCT/MODEL/productModelObject/getModelPropertyByRelated', { propertyId: modelProperty.id });
    
                        if (relatedData && relatedData.length > 0) {
                            showResultMessage({
                                success: false,
                                message: '[' + modelObject.objectName + ']已被其它对象引用，不能删除！',
                            });
                        }
                        else {
                            ids.push(modelProperty.id);
                        }
    
                    });
                    if (ids.length > 0) {
                        ajax('PRODUCT/MODEL/productModelObject/deleteModelProperties', { ids: ids }, (data) => {
                            propertyListRef.loadData({ id: modelObject.id });
                        });
                    }
                }
            };
        }
    
        render() {
    
            const propertyTableProps = {
                ref: (inst) => { this.propertyListRef = inst },
                tableConfigId: props.tableConfigId,
                dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelObjectProperties',
                autoLoad: false,
                selectMode: 'multi',
                bordered: false,
                actionGroupId: props.actionGroupId,
                rowActionGroupId: props.rowActionGroupId,
                actionHandler: this.actionHandler,
                setToolbarState: (topToolBar, selectedIds) => {
                    if (selectedIds.length > 0) {
                        topToolBar.enable('delete');
                        topToolBar.enable('edit');
                    }
                    else {
                        topToolBar.disable('delete');
                        topToolBar.disable('edit');
                    }
                },
                onSelectChange:
                    (selectRowKeys) => {
                        this.selectPropertyIds = selectRowKeys;
                    }
                ,
            };
    
            const formProps = {
                ref: (inst) => { this.propertyFormRef = inst },
                formConfigId: props.formConfigId,
                actionGroupId: 'saveActionGroup',
                actionHandler: this.actionHandler,
                inPop: true,
                destroyOnClose: true,
                title: this.state.formTitle,
            }
    
            return (
                <UIDataTableView {...propertyTableProps} {...this.props}>
                    <UIFormView {...formProps} />
                </UIDataTableView>
            );
        }
    }

    return ModelPropertyListTabPanel;
}

/**
 * 模型对象编辑Tab页面
 */
const WarpModelObjectEditTabPanel = (props) => {

    class ModelObjectEditTabPanel extends React.Component {

        changeModelObject = (value) => {
            
            const {history,location} = this.props;

            ajax('PRODUCT/MODEL/productModelObject/getModelObjectById',{id : value.key},(data) => {
               history.push(location.pathname, data);
                setTimeout(() => {
                    this.onTabChange(this.objectEditTab.getActivedTab());
                });
            });
        }

        onTabChange = (tabName) => {

            const modelObject = this.props.location.state;

            if(props.onTabChange !== undefined){
                props.onTabChange(tabName,modelObject);
            }
        }
    
        render() {

            const modelObject = this.props.location.state;

            const tabPanelMap = props.getTabPanelMap(this.props);
    
            const objectEditTabsProps = {
                title: <span> <UIIcon icon={props.titleIcon} /> {modelObject.packageName + '.' + modelObject.objectName} </span>,
                extra: <React.Fragment>跳转到 <ProductModelObjectSelect domainId={this.props.modelDomain.id} objectType={props.modelObjectType} style={{width : '200px'}} onSelectModelObject={this.changeModelObject}/><Divider type="vertical" /> <UIActionBar {...this.props} actionGroupId='goBackActionGroup' actionHandler={() => { }} /></React.Fragment>,
                tabConfigId: props.tabConfigId,
                onTabChange: this.onTabChange,
                tabContentMap: tabPanelMap,
                ref : (inst) => { this.objectEditTab = inst }
            }
    
            return (
                <UICardTabs {...objectEditTabsProps} {...this.props}>
    
                </UICardTabs>
            );
        }
    }

    return ModelObjectEditTabPanel;
}

/**
 * 模型对象列表高阶组件
 */
const WarpModelObjectListPanel = (props) => {

    class WarpModelObjectListPanel extends React.Component {

        constructor(props) {
            super(props);
            this.state = {
                domainId: -1,
            }
        }

        loadDomainData = (domainId) => {
            this.setState({ domainId: domainId });
            setTimeout(() => {
                let packageType = '';
                switch (props.objectType) {
                    case 'DB':
                        packageType = 'DB';
                       
                        break;
                    case 'DAO':
                        packageType = 'DAO';
                       
                        break;
                    case 'SERVICE':
                        packageType = 'SERVICE';
                       
                        break;
                    case 'DTO':
                        packageType = 'SERVICE';
                       
                        break;
                    case 'ENUM':
                        packageType = 'SERVICE';
                       
                        break;
                    default:
                        break;
                }

                this.objectListRef.clearForm();
                this.objectListRef.setSearchFormParams({ domainId: domainId, packageType: packageType });

                setTimeout(() => {
                    this.objectListRef.loadData({ domainId: domainId });
                });
                
            });
        }

        actionHandler = (actionEvent) => {
            const { objectListRef, selectModelObjectIds } = this;
            const { domainId } = this.state;

            const extActions = props.actionHandler !== undefined ? props.actionHandler(actionEvent, this) : {};

            const actions = {
                refresh: () => {
                    objectListRef.loadData({ domainId: domainId });
                },
                doDelete: () => {

                    const selectModelObjects = isNull(actionEvent.params) === false ? [actionEvent.params] : objectListRef.getSelectedDatas();

                    const ids = [];

                    const urlList = [];

                    const paramsList = [];

                    selectModelObjects.map(modelObject => {

                        urlList.push('PRODUCT/MODEL/productModelObject/queryModelObjectRelates');

                        paramsList.push({ relatedObjectId: modelObject.id, relatedType: 'MAP_DAO,DEPEND,RELATE_QUERY,RELATE_OPERATION,MAP_TABLE' });

                        ids.push(modelObject.id);

                    });

                    batchAjax(urlList,paramsList,(args) => {
                        let deleteIds = [];

                        args.map((data,index) => {
                            if(data.total > 0){
                                showResultMessage({
                                    success: false,
                                    message: '[' + selectModelObjects[index].objectName + ']象已被其它对象引用，不能删除',
                                });
                            }
                            else{
                                deleteIds.push(ids[index]);
                            }
                        });

                        if (deleteIds.length > 0) {
                            ajax('PRODUCT/MODEL/productModelObject/deleteModelObjects', { ids: deleteIds }, (data) => {
                                objectListRef.loadData({ domainId: domainId });
                            });
                        }
                        
                    });
                }
            };

            return { ...actions, ...extActions };
        }

        onSelectModelPackage = (packageId) => {
            this.setState({selectedPackage : packageId});
        }

        render() {

            const {pageHistory} = this.props;

            const { domainId } = this.state;

            if(domainId === -1){
                return <div/>
            }

            let packageType = '';

            let actionGroupId = '';

            let rowActionGroupId = '';

            switch (props.objectType) {
                case 'DB':
                    packageType = 'DB';
                    actionGroupId = 'tableObjectListActionGroup';
                    rowActionGroupId = 'tableObjectRowActionGroup';
                    break;
                case 'DAO':
                    packageType = 'DAO';
                    actionGroupId = 'daoObjectListActionGroup';
                    rowActionGroupId = 'daoObjectRowActionGroup';
                    break;
                case 'SERVICE':
                    packageType = 'SERVICE';
                    actionGroupId = 'serviceObjectListActionGroup';
                    rowActionGroupId = 'serviceObjectRowActionGroup';
                    break;
                case 'DTO':
                    packageType = 'SERVICE';
                    actionGroupId = 'dtoObjectListActionGroup';
                    rowActionGroupId = 'dtoObjectRowActionGroup';
                    break;
                case 'ENUM':
                    packageType = 'SERVICE';
                    actionGroupId = 'enumObjectListActionGroup';
                    rowActionGroupId = 'enumObjectRowActionGroup';
                    break;
                default:
                    break;
            }

            const modelObjTableProps = {
                history : pageHistory,
                tableConfigId: 'modelObjectList',
                actionGroupId: actionGroupId,
                rowActionGroupId: rowActionGroupId,
                dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelObjects?objectType=' + props.objectType,
                autoLoad: false,
                bordered: false,
                selectMode: 'multi',
                searchFormId: 'modelObjectSearchForm',
                actionHandler: this.actionHandler,
                params: { domainId: domainId, packageType: packageType },
                ref: (inst) => { this.objectListRef = inst },
                setToolbarState: (topToolBar, selectedIds) => {
                    if (selectedIds.length > 0) {
                        topToolBar.enable('delete');
                        topToolBar.enable('edit');
                    }
                    else {
                        topToolBar.disable('delete');
                        topToolBar.disable('edit');
                    }

                    if (props.setToolbarState != null) {
                        props.setToolbarState(topToolBar, selectedIds);
                    }
                },
                onSelectChange: (selectRowKeys) => {
                    this.selectModelObjectIds = selectRowKeys;
                    this.setState({ selectModelObjectIds: selectRowKeys });
                },
                // cellRender : (column,CellContent,data,dataSet) => {
                //     if(column.property === 'objectName'){
                //         CellContent.splice(0, 0, <Badge key={data.id} status={data.status === 'IN_USE' ? 'processing' : 'error'} />);
                //     }
                // }
            };

            //console.log(this.props);

            return (
                <UIDataTableView  {...modelObjTableProps}>
                    {domainId !== -1 && props.children !== undefined ? props.children(this) : null}
                </UIDataTableView>
            );
        }
    }

    return WarpModelObjectListPanel;
}

/**
 * 模型对象代码预览页面
 */
const WarpModelObjectCodePreviewPanel = (props) => {

    class ModelObjectCodePreviewPanel extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                modelObjectCode: '',
                defaultCodeTemplateId : 0,
                loading : false,
            }
        }

        setModelObject = (modelObject) => {
            this.modelObject = modelObject;
            
            ajax('PRODUCT/MODEL/productModelObject/queryModelCodeTemplateList',{targetType :props.targetType,inputObjectType : 'MODEL_OBJECT'},(data) => {
                
                if(data.records !== undefined){
                    let actionBeans = data.records.map( (codeTemplate) => {
                        return {
                            id : codeTemplate.id,
                            label : codeTemplate.templateName,
                        };
                    } );
    
                    const chooseCodeTemplateAction = {
                        subActionBeans : actionBeans,
                        type : 'radio',
                        icon : 'file-code',
                        id : 'chooseDaoTemplate',
                        handler : 'changeDaoTemplate',
                    };
    
                    this.modelObjectCodeView.setToolbarActionGroup({actionBeans:[chooseCodeTemplateAction],id : 'daoCodePreviewActionGroup'});
    
                    if(actionBeans.length > 0){
                        setTimeout(() => {
                            this.setState({loading : true});
                            ajax('PRODUCT/MODEL/productModelObject/genModelobjectCode',{id :modelObject.id,templateId : actionBeans[0].id},(data) => {
                                this.setState({modelObjectCode:data,selectedCodeTemplateId : actionBeans[0].id,loading : false});
                            });
                        });
                    }
                }
            });
        }

        actionHandler = (actionEvent) => {
            const { modelObject } = this;
           
            return {
                changeDaoTemplate : () => {
                    this.setState({loading : true});
                    ajax('PRODUCT/MODEL/productModelObject/genModelobjectCode',{id :modelObject.id,templateId : actionEvent.params},(data) => {
                        this.setState({modelObjectCode:data,selectedCodeTemplateId : actionEvent.params,loading : false});
                    });
                },
            }
        }
    
        render() {
            
            return (
                <UIView  bordered={false} actionGroupId="daoCodePreviewActionGroup" toolbarValue={this.state.selectedCodeTemplateId} actionHandler={this.actionHandler} ref={(inst) => this.modelObjectCodeView = inst}>
                    <Spin tip="代码生成中..." spinning={this.state.loading}>
                    <AceEditor mode="java" theme="github" width="100%" readOnly={true} value={this.state.modelObjectCode} ref={ (inst) => this.modelObjectCodeEditor = inst } />
                    </Spin>
                </UIView>
            );
        }
    }

    return ModelObjectCodePreviewPanel;
}

/** 
 * 数据库表对象列表
*/
const ProductDataTableListPanel = WarpModelObjectListPanel({
    objectType: 'DB', actionHandler: (actionEvent, owner) => {
        return {
            exportDaoObject: () => {
                    owner.exportDaoObjectModlaRef.openModal({
                    domainId: owner.state.domainId,
                    selectModelObjects: owner.objectListRef.getSelectedDatas(),
                });
            },
            addNew: () => {
                owner.addNewTableObjectRef.openModal();
            },
            doSave: () => {
                const { domainId } = owner.state;
                owner.addNewTableObjectRef.getFormData((formData) => {

                    formData.objectType = "DB";

                    ajax('PRODUCT/MODEL/productModelObject/saveModelObject', formData, (data) => {
                        owner.addNewTableObjectRef.closeModal();
                        owner.objectListRef.loadData({domainId : domainId});
                    });
                });
            }
        };
    },
    setToolbarState: (topToolBar, selectedIds) => {
        if (selectedIds.length > 0) {
            topToolBar.enable('exportDaoObject');
        }
        else {
            topToolBar.disable('exportDaoObject');
        }
    },
    children: (owner) => {
        
        const { selectModelObjectIds, domainId } = owner.state;

        return (
            <React.Fragment>
                <StartJobModal key='ExportDaoObjectModal'
                    jobTitle='导出DAO对象'
                    startJobUrl="PRODUCT/MODEL/productModelObject/importDaoObjectsJob"
                    startJobParamData={{ tableIds: selectModelObjectIds}}
                    checkJobUrl="PRODUCT/MODEL/productModelObject/checkImportDaoObjectsJob"
                    checkJobParamData={{ }}
                    onSelectModelPackage={this.onSelectModelPackage}
                    packageType="DAO"
                    ref={(inst) => owner.exportDaoObjectModlaRef = inst}
                    renderItem={(item) => {
                        return (<List.Item><span><UIIcon icon='table' />{item.objectName}</span></List.Item>)
                    }
                    }
                />
                <UIFormView
                    ref={(inst) => owner.addNewTableObjectRef = inst}
                    title="新建数据表对象"
                    params={{ domainId: domainId, packageType: 'DB' }}
                    actionGroupId="saveActionGroup"
                    actionHandler={owner.actionHandler}
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="addNewProductTableObjectForm"
                />
            </React.Fragment>
        );
    }
});

/** 
 * 数据访问对象列表
*/
const ProductDaoObjectListPanel = WarpModelObjectListPanel({
    objectType: 'DAO', actionHandler: (actionEvent, owner) => {
        return {
            exportDtoObject: () => {
                
                owner.exportDtoObjectModlaRef.openModal({
                    domainId: owner.state.domainId,
                    selectModelObjects: owner.objectListRef.getSelectedDatas(),
                });
            },
        };
    },
    setToolbarState: (topToolBar, selectedIds) => {
        if (selectedIds.length > 0) {
            topToolBar.enable('exportDtoObject');
        }
        else {
            topToolBar.disable('exportDtoObject');
        }
    },
    children: (owner) => {
        //console.log(owner);

        const { selectedPackage, selectModelObjectIds, domainId } = owner.state;

        const packageId = selectedPackage != null ? selectedPackage.id : 0;

        return (
            <React.Fragment>
                <StartJobModal key='ExportDToObjectModal'
                    jobTitle='导出DTO对象'
                    startJobUrl="PRODUCT/MODEL/productModelObject/importDtoObjectsJob"
                    startJobParamData={{ daoIds: selectModelObjectIds}}
                    checkJobUrl="PRODUCT/MODEL/productModelObject/checkImportDtoObjectsJob"
                    checkJobParamData={{ }}
                    onSelectModelPackage={this.onSelectModelPackage}
                    packageType="SERVICE"
                    ref={(inst) => owner.exportDtoObjectModlaRef = inst}
                    renderItem={(item) => {
                        return (<List.Item><span><UIIcon icon='cog' />{item.objectName}</span></List.Item>)
                    }
                    }
                />
            </React.Fragment>
        );
    }
});

/** 
 * 数据包装对象列表
*/
const ProductDtoObjectListPanel = WarpModelObjectListPanel({
     objectType: 'DTO',
     actionHandler: (actionEvent, owner) => {
        return {
            exportDaoObject: () => {
               
                owner.exportDaoObjectModlaRef.openModal({
                    domainId: owner.state.domainId,
                    selectModelObjects: owner.objectListRef.getSelectedDatas(),
                });
            },
            addNew: () => {
                owner.addNewDtojectRef.openModal();
            },
            doSave: () => {
                const { domainId } = owner.state;
                owner.addNewDtojectRef.getFormData((formData) => {

                    formData.objectType = "DTO";

                    ajax('PRODUCT/MODEL/productModelObject/saveModelObject', formData, (data) => {
                        owner.addNewDtojectRef.closeModal();
                        owner.objectListRef.loadData({domainId : domainId});
                    });
                });
            }
        };
    },
    setToolbarState: (topToolBar, selectedIds) => {
        if (selectedIds.length > 0) {
            topToolBar.enable('exportDaoObject');
        }
        else {
            topToolBar.disable('exportDaoObject');
        }
    },
    children: (owner) => {
        const { selectedPackage, selectModelObjectIds, domainId } = owner.state;

        const packageId = selectedPackage != null ? selectedPackage.id : 0;
        return (
            <React.Fragment>
                
                <UIFormView
                    ref={(inst) => owner.addNewDtojectRef = inst}
                    title="新建DTO对象"
                    params={{ domainId: domainId, packageType: 'SERVICE' }}
                    actionGroupId="saveActionGroup"
                    actionHandler={owner.actionHandler}
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="addNewProductDtoForm"
                />
            </React.Fragment>
        );
    }
});

/** 
 * 数据枚举对象列表
*/
const ProductEnumObjectListPanel = WarpModelObjectListPanel({ 
    objectType: 'ENUM',
    actionHandler: (actionEvent, owner) => {
        return {
            
            addNew: () => {
                owner.addNewEnumObjectRef.openModal();
            },
            doSave: () => {
                const { domainId } = owner.state;
                owner.addNewEnumObjectRef.getFormData((formData) => {

                    formData.objectType = "ENUM";

                    ajax('PRODUCT/MODEL/productModelObject/saveModelObject', formData, (data) => {
                        owner.addNewEnumObjectRef.closeModal();
                        owner.objectListRef.loadData({domainId : domainId});
                    });
                });
            }
        };
    },
    children: (owner) => {
        const { selectedPackage, selectModelObjectIds, domainId } = owner.state;

        const packageId = selectedPackage != null ? selectedPackage.id : 0;
        return (
            <React.Fragment>
                
                <UIFormView
                    ref={(inst) => owner.addNewEnumObjectRef = inst}
                    title="新建枚举对象"
                    params={{ domainId: domainId, packageType: 'SERVICE' }}
                    actionGroupId="saveActionGroup"
                    actionHandler={owner.actionHandler}
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="addNewProductEnumForm"
                />
            </React.Fragment>
        );
    }
});

/** 
 * 数据服务对象列表
*/
const ProductServiceObjectListPanel = WarpModelObjectListPanel({ 
    objectType: 'SERVICE',
    actionHandler: (actionEvent, owner) => {
        return {
            
            addNew: () => {
                owner.addNewServiceObjectRef.openModal();
            },
            doSave: () => {
                const { domainId } = owner.state;
                owner.addNewServiceObjectRef.getFormData((formData) => {

                    formData.objectType = "SERVICE";

                    ajax('PRODUCT/MODEL/productModelObject/saveModelObject', formData, (data) => {
                        owner.addNewServiceObjectRef.closeModal();
                        owner.objectListRef.loadData({domainId : domainId});
                    });
                });
            }
        };
    },
    children: (owner) => {
        const { domainId } = owner.state;

        return (
            <React.Fragment>
                
                <UIFormView
                    ref={(inst) => owner.addNewServiceObjectRef = inst}
                    title="新建服务对象"
                    params={{ domainId: domainId, packageType: 'SERVICE' }}
                    actionGroupId="saveActionGroup"
                    actionHandler={owner.actionHandler}
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="addNewServiceObjectForm"
                />
            </React.Fragment>
        );
    }
});

/** 
 * 导入数据表对象
*/
class ImportDataTablePanel extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            selectTableIds: [],
            importPercent: 0,
            database: null,
            selectedPackage: null,
        };
    }

    onSelectDatabase = (database) => {
        this.setState({ database: database });
        setTimeout(() => {
            this.tableListRef.loadData({ databaseId: database.id });
        });
    }

    componentDidMount() {
        if (getStoreItem('lastSelectDatabaseId')) {
            ajax('PRODUCT/MODEL/productDatabase/getProductDatabaseById', { id: getStoreItem('lastSelectDatabaseId') }, (data) => {
                this.onSelectDatabase(data);
            });
        }
    }

    actionHandler = (actionEvent) => {

        const { selectTableIds, tableListRef } = this;

        return {
            refresh: () => {
                tableListRef.loadData();
            },
            importTables: () => {
                this.importModal.openModal();
            },
            doImport: () => {
                this.importModal.closeModal();
                setTimeout(() => {
                    this.startJob.start();
                }, 0);
            }
        };
    }

    onSelectModelPackage = (modelPackage) => {
        this.setState({ selectedPackage: modelPackage });
        this.importModal.getToolbar().enable('importDataTable');
    }

    render() {

        const { modelDomain } = this.props;

        const { selectTableIds, selectedPackage, database } = this.state;

        const databaseId = isNotNull(database) ? database.id : 0;

        const packageId = isNotNull(selectedPackage) ? selectedPackage : 0;

        const tableProps = {
            title: '导入数据库表对象',
            ref: (inst) => { this.tableListRef = inst },
            extra: <span><ProductDatabaseSelect onSelectDatabase={this.onSelectDatabase}></ProductDatabaseSelect><Divider type="vertical" /><UIActionBar {...this.props} actionGroupId='goBackActionGroup' actionHandler={() => { }} /></span>,
            tableConfigId: 'productDatabaseTableInfoTable',
            actionGroupId: 'databaseTableListActionGroup',
            actionHandler: this.actionHandler,
            searchFormId: 'databaseTableSearchForm',
            dataUrl: 'PRODUCT/MODEL/productDatabase/queryDatabaseTables',
            autoLoad: false,
            selectMode: 'multi',
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    topToolBar.enable('ok');
                }
                else {
                    topToolBar.disable('ok');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.setState({ selectTableIds: selectRowKeys });
                }
            ,
        };

        const importViewProps = {
            ref: (inst) => { this.importModal = inst },
            title: '导入数据库表对象',
            actionGroupId: 'importTableActionGroup',
            actionHandler: this.actionHandler,
            inPop: true,
            destroyOnClose: true,
            setToolbarState: (toolbar) => {
                toolbar.disable('importDataTable');
            },
        };

        const jobProps = {
            initValue: 0,
            checkInterval: 2000,
            startJobUrl: 'PRODUCT/MODEL/productDatabase/importDatabaseTables',
            startJobParamData: { databaseId: databaseId, packageId: packageId, tables: selectTableIds },
            checkJobUrl: 'PRODUCT/MODEL/productDatabase/checkImportDatabaseTables',
            checkJobParamData: { databaseId: databaseId },
            onJobFinish: (data) => {
                console.log(data);
                if (data.success) {
                    showResultMessage({
                        success: true,
                        message: '导入数据库表完成'
                    });
                }
                else {
                    showResultMessage({
                        success: false,
                        message: '导入数据库表错误:' + data.message
                    });
                }
            }
        };

        return (
            <UIDataTableView {...tableProps} >
                <UIView {...importViewProps}>
                    <Row gutter={8}>
                        <Col span={24}>
                            <ProductModelPackageSelect domainId={modelDomain.id} packageType="DB" onSelectModelPackage={this.onSelectModelPackage}></ProductModelPackageSelect>
                        </Col>
                        <Col span={24} style={{ marginTop: 8 }}>
                            <List
                                style={{ height: '300px', overflow: 'auto' }}
                                header={<div>已选数据表</div>}
                                bordered
                                dataSource={selectTableIds}
                                renderItem={item => (<List.Item><span><UIIcon icon='table' />{item}</span></List.Item>)}
                            />
                        </Col>
                    </Row>
                </UIView>
                <StartJobModla {...jobProps} title="导入进度" ref={(inst) => { this.startJob = inst }} />
            </UIDataTableView>
        );
    }
}

/**
 * 服务对象编辑Tab页面
 */
const ProductServiceObjectEditTabsPanel = WarpModelObjectEditTabPanel({
    modelObjectType : 'SERVICE',
    tabConfigId: 'serviceObjectTab',
    titleIcon: 'cogs',
    onTabChange: (tabName,modelObject) => {
        
        switch (tabName) {
            case 'productModelServiceObjectTabItem':
                this.serviceFormRef.setModelObject(modelObject);
                break;
            case 'productModelServiceMethodTabItem':
                this.methodListRef.setModelObject(modelObject);
                break;
            case 'objectDependTabItem':
                this.objectDependRef.setModelObject(modelObject);
                break;
            case 'objectCodePreviewTabItem':
                this.objectCodePreviewRef.setModelObject(modelObject);
                break;
        }
    },
    getTabPanelMap: (warpedProps) => {
        return {
            '/productServiceObjectBasicInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductServiceObjectBasicInfoPanel {...warpedProps} ref={(inst) => this.serviceFormRef = inst} />);
                }
            },
            '/productServiceMethodListPanel' : {
                getComponent: (owner, props) => {
                    return (<ProductServiceMethodListPanel {...warpedProps} ref={(inst) => this.methodListRef = inst} />);
                }
            },
            '/productServiceObjectDependPanel': {
                getComponent: (owner, props) => {
                    return (<ProductServiceObjectDependPanel {...warpedProps} ref={(inst) => this.objectDependRef = inst} />);
                }
            },
            '/productServiceObjectCodePreviewPanel': {
                getComponent: (owner, props) => {
                    return (<ProductServiceObjectCodePreviewPanel {...warpedProps} ref={(inst) => this.objectCodePreviewRef = inst} />);
                }
            },  
        }
    },
});

/**
 * 服务对象基本信息表单
 */
const ProductServiceObjectBasicInfoPanel = WarpModelObjectFormPanel({formConfigId : 'serviceObjectForm'});

/**
 * 服务方法列表
 */
class ProductServiceMethodListPanel extends React.Component {
    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        this.serviceMethodListRef.loadData({serviceObjectId :modelObject.id});
    }

    actionHandler = (actionEvent) => {

        const { modelObject ,addNewServiceMethodRef,serviceMethodListRef,selectedIds,serviceMethodEditTab} = this;

        return {
            refresh : () => {
                serviceMethodListRef.loadData({serviceObjectId :modelObject.id});
            },
            addNew : () => {
                addNewServiceMethodRef.openModal();
            },
            doSave : () => {
                addNewServiceMethodRef.getFormData((formData) => {

                    formData.objectId = modelObject.id;

                    ajax('PRODUCT/MODEL/productModelObject/saveModelService',formData,(data) => {
                        addNewServiceMethodRef.closeModal();
                        serviceMethodListRef.loadData({serviceObjectId :modelObject.id});
                    });
                });
            },
            doDelete : () => {
                const selectServiceIds = isNull(actionEvent.params) === false ? [actionEvent.params.id] : selectedIds;
                
                ajax('PRODUCT/MODEL/productModelObject/deleteModelServices',{ids : selectServiceIds},(data) => {
                    serviceMethodListRef.loadData({serviceObjectId :modelObject.id});
                });
            },
            doEdit : () => {
                this.editedServiceMethod = actionEvent.params;
                serviceMethodEditTab.openModal(() => {
                    this.onTabChange('productModelServiceTabItem');
                });
            },
            closeDialog : () => {
                serviceMethodEditTab.closeModal();
            }
        }
    }

    onTabChange = (tabName) => {
        const {editedServiceMethod} = this;
        switch (tabName) {
            case 'productModelServiceTabItem':
            this.serviceFormRef.setModelService(editedServiceMethod);
            break;
            case 'productModelServiceParameterTabItem':
            this.serviceParamListRef.setModelService(editedServiceMethod);
            break;
           
        }
    }

    render() {
        const tableProps = {
            bordered : false,
            ref: (inst) => { this.serviceMethodListRef = inst },
            tableConfigId: 'productServiceMethodListTable',
            actionGroupId: 'productServiceMethodListActionGroup',
            rowActionGroupId : 'productServiceMethodRowActionGroup',
            actionHandler: this.actionHandler,
            dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelServiceList',
            autoLoad: false,
            selectMode: 'multi',
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    topToolBar.enable('delete');
                }
                else {
                    topToolBar.disable('delete');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectedIds = selectRowKeys;
                }
            ,
        };

        const tabPanelContentMap ={
            '/productServiceMethodInfoPanel': {
                getComponent: (owner, props) => {
                    return <ProductServiceMethodInfoPanel {...props} ref={(inst) => this.serviceFormRef = inst}/>;
                }
            },
            '/productServiceMethodParameterPanel': {
                getComponent: (owner, props) => {
                    return <ProductServiceMethodParameterPanel {...props} ref={(inst) => this.serviceParamListRef = inst}/>;
                }
            },
        }

        return (
            <React.Fragment>
                <UIDataTableView {...tableProps}>

                </UIDataTableView>
                <UIFormView
                    ref={(inst) => this.addNewServiceMethodRef = inst}
                    title="新建服务方法"
                    actionGroupId="saveActionGroup"
                    actionHandler={this.actionHandler}
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="addNewProductServiceForm"
                />
                <UITabsView
                    actionGroupId="defaultDiaoligOkActionGroup"
                    actionHandler={this.actionHandler}
                    width={900}
                    ref={(inst) => { this.serviceMethodEditTab = inst; }}
                    tabConfigId="productModelServiceEditorTab"
                    title="编辑服务方法"
                    onTabChange={this.onTabChange}
                    tabContentMap={tabPanelContentMap}
                    inPop={true}
                    destroyOnClose={true}
                />
            </React.Fragment>
            
        );
    }
}

/**
 * 服务方法基本信息
 */
class ProductServiceMethodInfoPanel extends React.Component {

    setModelService = (serviceMethod) => {
        this.serviceMethodFormRef.setFormData(serviceMethod);
    }

    render() {
        const objectFormProps = {
            formConfigId: 'productServiceForm',
            wrappedComponentRef: (inst) => this.serviceMethodFormRef = inst,
            actionGroupId: 'saveActionGroup',
            actionHandler: this.actionHandler,
        }
        return (
            <UIForm {...objectFormProps}>

            </UIForm>
        );
    }
}

/**
 * 服务方法参数列表
 */
class ProductServiceMethodParameterPanel extends React.Component {

    state = {
        chooseDataTypeActionHandler : null,
    }

    setModelService = (serviceMethod) => {
        this.serviceMethod = serviceMethod;
        this.inputParamListRef.loadData({serviceId:serviceMethod.id});
        ajax('PRODUCT/MODEL/productModelObject/getServiceOutputParameter',{serviceId:serviceMethod.id},(data) => {
            this.outputParam = data;
            this.outputParamFormRef.setFormData(data);
        });
    }

    outputParamActionHandler = (actionEvent) => {
        const {serviceMethod} = this;
        let {outputParam} = this;
        return {
            chooseDataType : () => {
                this.setState({chooseDataTypeActionHandler : this.outputParamActionHandler});
                this.chooseDataTypeRef.openModal(()=> {
                    
                    if(this.chooseModelObjectRef !== undefined){
                        this.chooseModelObjectRef.loadData({objectType : 'DTO,QUERY_BEAN'});
                    }
                    if(this.chooseBasicDataTypeRef !== undefined){
                        this.chooseBasicDataTypeRef.loadData({objectType : 'DATA_TYPE'});
                    }
                });
            },
            doOk : () => {
                ajax('PRODUCT/MODEL/productModelObject/getModelObjectById',{id : this.selectedObjectId},(data) => {

                    if(isNull(outputParam)){
                        outputParam = {};
                    }

                    outputParam.dataTypeId = data.id;
                    outputParam.dataType = data.objectName;

                    this.outputParamFormRef.setFormData(outputParam);
                    this.chooseDataTypeRef.closeModal();
                });
                
            },
            clearOutputParam : () => {
                if(isNull(outputParam)){
                    outputParam = {};
                }

                outputParam.dataTypeId = 0;
                outputParam.dataType = '';

                this.outputParamFormRef.setFormData(outputParam);
            },
            closeDialog : () => {
                this.chooseDataTypeRef.closeModal();
            },
            doSave : () => {
                this.outputParamFormRef.getFormData((data) => {
                    data.serviceId = serviceMethod.id;
                    data.parameterType = 'OUTPUT';
                    ajax('PRODUCT/MODEL/productModelObject/saveServiceParameter',data,(result) => {
                        outputParam = result;
                    });
                });
            }
        };
    }

    inputParamListActionHandler = (actionEvent) => {
       
        const {serviceMethod,inputParamFormRef,selectInputParamIds} = this;
        return {
            addNewInputParameter : () => {
                inputParamFormRef.openModal();
            },
            chooseInputDataType : () => {
                this.setState({chooseDataTypeActionHandler : this.inputParamListActionHandler});
                this.chooseDataTypeRef.openModal(()=> {
                    
                    if(isNotNull(this.chooseModelObjectRef)){
                        this.chooseModelObjectRef.loadData({objectType : 'DTO,QUERY_BEAN'});
                    }
                    if(isNotNull(this.chooseBasicDataTypeRef)){
                        this.chooseBasicDataTypeRef.loadData({objectType : 'DATA_TYPE'});
                    }
                });
            },
            doOk : () => {
                ajax('PRODUCT/MODEL/productModelObject/getModelObjectById',{id : this.selectedObjectId},(data) => {

                    const inputParam = {
                        dataTypeId : data.id,
                        dataType : data.objectName,
                    }

                    inputParamFormRef.setFormData(inputParam);
                    this.chooseDataTypeRef.closeModal();
                });
                
            },
            closeDialog : () => {
                this.chooseDataTypeRef.closeModal();
            },
            closeInputParamDialog : () => {
                inputParamFormRef.closeModal();
            },
            doSave : () => {
                const dataList = this.inputParamListRef.getListData();
                inputParamFormRef.getFormData((data) => {
                    data.serviceId = serviceMethod.id;
                    data.parameterType = 'INPUT';
                    if(data.sortIndex === undefined){
                        data.sortIndex = dataList.length;
                    }
                    ajax('PRODUCT/MODEL/productModelObject/saveServiceParameter',data,(result) => {
                        inputParamFormRef.closeModal();
                        this.inputParamListRef.loadData({serviceId:serviceMethod.id});
                    });
                });
            },
            editInputParameter : () => {
                const inputParam = actionEvent.params;
                inputParamFormRef.openModal(() => {
                    inputParamFormRef.setFormData(inputParam);
                })
            },
            deleteInputParameter : () => {
                const selectIds = isNull(actionEvent.params) ? selectInputParamIds : [actionEvent.params];
                ajax('PRODUCT/MODEL/productModelObject/deleteModelServiceParameters',{parameterIds : selectIds},() => {
                    this.inputParamListRef.loadData({serviceId:serviceMethod.id});
                });
            },
            moveUp : () => {
                const inputParam = actionEvent.params;
                const dataList = this.inputParamListRef.getListData();
                let lastInputParam = null;
                if(inputParam.sortIndex > 0){
                    inputParam.sortIndex = inputParam.sortIndex - 1;

                    for(let i=0;i< dataList.length;i++ ){
                        if(dataList[i].id !== inputParam.id){
                            lastInputParam = dataList[i];
                        }
                        else{
                            break;
                        }
                    }

                    if(lastInputParam !== null){
                        lastInputParam.sortIndex = lastInputParam.sortIndex + 1;
                    }

                    batchAjax(['PRODUCT/MODEL/productModelObject/saveServiceParameter','PRODUCT/MODEL/productModelObject/saveServiceParameter'],[inputParam,lastInputParam],() => {
                        this.inputParamListRef.loadData({serviceId:serviceMethod.id});
                    });
                }
            },
            moveDown : () => {
                const inputParam = actionEvent.params;
                const dataList = this.inputParamListRef.getListData();
                let lastInputParam = null;
                if(inputParam.sortIndex < dataList.length){
                    
                    for(let i=0;i< dataList.length;i++ ){
                        if(dataList[i].id !== inputParam.id && dataList[i].sortIndex > inputParam.sortIndex ){
                            lastInputParam = dataList[i];
                            break;
                        }
                    }

                    inputParam.sortIndex = inputParam.sortIndex + 1;

                    if(lastInputParam !== null){
                        lastInputParam.sortIndex = lastInputParam.sortIndex - 1;
                    }

                    batchAjax(['PRODUCT/MODEL/productModelObject/saveServiceParameter','PRODUCT/MODEL/productModelObject/saveServiceParameter'],[inputParam,lastInputParam],() => {
                        this.inputParamListRef.loadData({serviceId:serviceMethod.id});
                    });
                }
            }
        }
    }

    onTabChange = (tabName) => {
        this.chooseDataTypeToolbar.disable('ok');
        switch(tabName){
            case 'basicObjectTabItem' :
                this.chooseBasicDataTypeRef.loadData({objectType : 'DATA_TYPE'});
            break;
            case 'modelObjectTabItem' :
                this.chooseModelObjectRef.loadData({objectType : 'DTO,QUERY_BEAN'});
            break;
        }
    }

    render() {

        const tableProps = {
            bordered : false,
            ref: (inst) => { this.inputParamListRef = inst },
            tableConfigId: 'productModelServiceParameterTable',
            actionGroupId: 'inputParameterActionGroup',
            rowActionGroupId : 'inputParameterRowActionGroup',
            actionHandler: this.inputParamListActionHandler,
            dataUrl: 'PRODUCT/MODEL/productModelObject/queryServiceParameters?parameterType=INPUT',
            autoLoad: false,
            selectMode: 'multi',
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    topToolBar.enable('delete');
				    topToolBar.enable('edit');
                }
                else {
                    topToolBar.disable('delete');
                    topToolBar.disable('edit');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectInputParamIds = selectRowKeys;
                }
            ,
        };

        return (
            <React.Fragment>
                <Row style={{marginTop : '0px'}}>
                    <Col span={24}>
                        <Divider orientation="left">输出参数</Divider>
                        <UIForm actionGroupId="outputParameterActionGroup" actionHandler={this.outputParamActionHandler} params={{objectId : 0}} wrappedComponentRef={(inst) => this.outputParamFormRef = inst} formConfigId="productServiceOutputParameterForm"/>
                    </Col>
                </Row>
                <Row style={{marginTop : '0px'}}>
                    <Col span={24}>
                        <Divider orientation="left">输入参数</Divider>
                        <UIDataTableView {...tableProps} />
                    </Col>
                </Row>
                <UIFormView 
                    zIndex={2000}
                    title="输入参数"
                    inPop={true}
                    destroyOnClose={true}
                    formConfigId="productServiceInputParameterForm"
                    ref={ (inst) => { this.inputParamFormRef = inst } }
                    actionGroupId="inputParameterFormActionGroup"
                    actionHandler={this.inputParamListActionHandler}
                />
                <UITabsView 
                    zIndex={3000}
                    tabConfigId="chooseDataTypeTab"
                    bordered={false}
                    title="选择数据对象"
                    destroyOnClose={true}
                    width={800}
                    inPop={true}
                    actionGroupId="defaultDiaoligActionGroup"
                    actionHandler={this.state.chooseDataTypeActionHandler}
                    ref={(inst) => this.chooseDataTypeRef = inst}
                    onTabChange={this.onTabChange}
                    setToolbarState={
                        (topToolBar) => {
                            topToolBar.disable('ok');
                            this.chooseDataTypeToolbar = topToolBar;
                        }
                    }
                    tabContentMap={{
                        '/basicObjectListPanel': {
                            getComponent: (owner, props) => {
                                return (
                                    <UIDataTableView
                                        bordered={false}
                                        ref={(inst) => this.chooseBasicDataTypeRef = inst}
                                        tableConfigId="modelObjectList"
                                        dataUrl="PRODUCT/MODEL/productModelObject/queryModelObjects"
                                        selectMode="single"
                                        autoLoad={false}
                                        actionHandler={this.state.chooseDataTypeActionHandler}
                                        onSelectChange={
                                            (selectRowKeys) => {
                                                if(selectRowKeys.length > 0){
                                                    this.selectedObjectId = selectRowKeys[0];
                                                    this.chooseDataTypeToolbar.enable('ok');
                                                }
                                            }
                                        }
                                />);
                            }
                        },
                        '/modelObjectListPanel': {
                            getComponent: (owner, props) => {
                                //return <ProductServiceMethodParameterPanel {...props} ref={(inst) => this.serviceParamListRef = inst}/>;
                                return (
                                    <UIDataTableView
                                        bordered={false}
                                        ref={(inst) => this.chooseModelObjectRef = inst}
                                        tableConfigId="modelObjectList"
                                        searchFormId="modelObjectWithDomainSearchForm"
                                        dataUrl="PRODUCT/MODEL/productModelObject/queryModelObjects"
                                        selectMode="single"
                                        autoLoad={false}
                                        actionHandler={this.state.chooseDataTypeActionHandler}
                                        onSelectChange={
                                            (selectRowKeys) => {
                                                if(selectRowKeys.length > 0){
                                                    this.selectedObjectId = selectRowKeys[0];
                                                    this.chooseDataTypeToolbar.enable('ok');
                                                }
                                                
                                            }
                                        }
                                />);
                            }
                        },
                    }}
                />
                
            </React.Fragment>
        );
    }
}

/**
 * 服务依赖对象管理
 */
class ProductServiceObjectDependPanel extends React.Component {
    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        this.dependObjectListRef.loadData({objectId :modelObject.id,relatedType: "DEPEND"});
    }

    actionHandler = (actionEvent) => {

        return {
            addRelation : () => {
                this.chooseModelObjectRef.openModal(() => {
                    this.chooseModelObjectRef.loadData({objectType : 'DAO,SERVICE'});
                });
            },
            removeRelation : () => {

                const selectIds = isNull(actionEvent.params) ? this.selectRelatedIds : [actionEvent.params.id];

                ajax('PRODUCT/MODEL/productModelObject/removeRelatedModelObjects',{ids : selectIds },(data) => {
                    this.setModelObject(this.modelObject);
                });
            },
            close : () => {
                this.chooseModelObjectRef.closeModal();
            },
            doSave : () => {

               ajax('PRODUCT/MODEL/productModelObject/addModelObjectRelates',{objectId : this.modelObject.id,relatedObjectIds : this.selectedObjectIds,relatedType : 'DEPEND'},(data) => {
                this.chooseModelObjectRef.closeModal();
                this.setModelObject(this.modelObject);
               });
            },
            applyServiceTemplate : () => {

                const dependDaoObject = actionEvent.params;

                const {serviceTemplateWizardRef} = this;

                this.setState({dependDaoObject:dependDaoObject});

                serviceTemplateWizardRef.openModal();

            }
        };
    }

    onInitWizardStep  = (wizardStepId) => {
        
        if('viewServiceTemplateDetail' === wizardStepId && this.viewServiceTemplateRef !== null){
            this.viewServiceTemplateRef.loadServiceTemplateItems();
        }
       if('applyServiceTemplate' === wizardStepId && this.applyServiceTemplateRef !== null){
            const {dependDaoObject} = this.state;
            this.applyServiceTemplateRef.buildConfigForm(dependDaoObject);
       }
    }

    onWizardFinish = (wizardDataStore) => {
        
        const {serviceTemplateWizardRef} = this;

        const {selectServiceTemplateIds,configValues} = wizardDataStore;

        ajax("PRODUCT/MODEL/productModelObject/addNewProductServiceByTemplate",{serviceId : this.modelObject.id,templateId:selectServiceTemplateIds[0],inputObjectMap : configValues},(data) => {
            serviceTemplateWizardRef.closeModal();
        })
    }

    render() {
        const tableProps = {
            bordered : false,
            ref: (inst) => { this.dependObjectListRef = inst },
            tableConfigId: 'modelObjectRelatedList',
            actionGroupId: 'serviceObjectDependActionGroup',
            rowActionGroupId : 'serviceObjectDependRowActionGroup',
            actionHandler: this.actionHandler,
            dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelObjectRelates',
            autoLoad: false,
            selectMode: 'multi',
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    topToolBar.enable('removeRelation');
                }
                else {
                    topToolBar.disable('removeRelation');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectRelatedIds = selectRowKeys;
                }
            ,
        };

        const tabPanelMap = {
            '/ChooseServiceTemplatePanel': {
                getComponent: (owner, props) => {
                    return (<ChooseServiceTemplatePanel {...this.props} {...props} ref={(inst) => this.chooseServiceTemplateRef = inst} />);
                }
            },
            '/ViewServiceTemplatePanel': {
                getComponent: (owner, props) => {
                    return (<ViewServiceTemplatePanel {...this.props} {...props} ref={(inst) => this.viewServiceTemplateRef = inst} />);
                }
            },
            '/ApplyServiceTemplatePanel': {
                getComponent: (owner, props) => {
                    return (<ApplyServiceTemplatePanel {...this.props} {...props} ref={(inst) => this.applyServiceTemplateRef = inst} />);
                }
            },
        };

        return (
            <React.Fragment>
                <UIDataTableView {...tableProps}>

                </UIDataTableView>
                <UIDataTableView
                    bordered={false}
                    title="选择依赖对象"
                    destroyOnClose={true}
                    width={900}
                    inPop={true}
                    ref={(inst) => this.chooseModelObjectRef = inst}
                    tableConfigId="modelObjectList"
                    searchFormId="modelObjectWithDomainSearchForm"
                    dataUrl="PRODUCT/MODEL/productModelObject/queryModelObjects"
                    selectMode="multi"
                    autoLoad={false}
                    actionGroupId="saveAndCloseActionGroup"
                    actionHandler={this.actionHandler}
                    onSelectChange={
                        (selectRowKeys) => {
                            this.selectedObjectIds = selectRowKeys;
                        }
                    }
                />
                <UIView title="应用服务模板向导" destroyOnClose={true} width={900} inPop={true} ref={ (inst) => this.serviceTemplateWizardRef = inst }>
                    <UIWizard
                        tabConfigId="applyServiceTemplateWizard" 
                        tabContentMap={tabPanelMap}
                        canGoNext={false}
                        onWizardStepChange={this.onWizardStepChange}
                        onInitWizardStep={this.onInitWizardStep}
                        onWizardFinish={this.onWizardFinish}
                    />
                </UIView>
            </React.Fragment>
            
        );
    }
}

/**
 * 选择服务模板
 */
class ChooseServiceTemplatePanel extends React.Component {

    constructor(props) {
        
        super(props);
        this.state = {
            stepDataStore : props.stepDataStore,
        }
    }

    componentDidMount() {
        const {stepDataStore} = this.state;

        if( this.props.changeWizardState !== undefined){
            this.props.changeWizardState({
                canGoNext : false,
                canGoPrev : false,
                canFinish : false,
            });
        }

        if(stepDataStore !== undefined ){
            this.chooseServiceTemplateRef.setSelected(stepDataStore.selectServiceTemplateIds);
        }
    }

    render(){
        const {stepDataStore} = this.state;

        const tableProps = {
            bordered : false,
            actionHandler: this.actionHandler,
            searchFormId : 'productModelServiceTemplateQueryForm',
			tableConfigId: 'productModelServiceTemplateTable',
			dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelServiceTemplateList',
			selectMode: 'single',
			autoLoad: true,
			ref: (inst) => { this.chooseServiceTemplateRef = inst },
			onSelectChange:
				(selectRowKeys) => {

                    if( this.props.changeWizardState !== undefined){
                        this.props.changeWizardState({
                            canGoNext : selectRowKeys !== undefined ? true : false,
                            canGoPrev : false,
                            canFinish : false,
                            //stepDataStore 
                        });
                    }

                    if(stepDataStore !== undefined ){
                        stepDataStore.selectServiceTemplateIds = selectRowKeys;
                    }

				}
			,
		};

        return (
            <UIDataTableView {...this.props} {...tableProps} />
        );
    }
}

/**
 * 查看服务模板
 */
class ViewServiceTemplatePanel extends React.Component {

    constructor(props) {
        
        super(props);
        this.state = {
            stepDataStore : props.stepDataStore,
        }
    }

    componentDidMount() {
        
        if( this.props.changeWizardState !== undefined){
            this.props.changeWizardState({
                canGoPrev : true,
                canGoNext : true,
            });
        }
    }

    loadServiceTemplateItems = () => {

        const {stepDataStore} = this.state;

        this.serviceTemplateItemListRef.loadData({serviceTemplateId : stepDataStore.selectServiceTemplateIds[0]});
    }

    render(){

        const tableProps = {
            bordered : false,
            ref: (inst) => { this.serviceTemplateItemListRef = inst},
			tableConfigId: 'productModelServiceTemplateItemTable',
			dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelServiceTemplateItemList',
			selectMode: 'none',
			autoLoad: false,
			ref: (inst) => { this.serviceTemplateItemListRef = inst },
		};
		
        return (
            <UIDataTableView {...this.props} {...tableProps} />
        );
    }
}

/**
 * 应用服务模板
 */
class ApplyServiceTemplatePanel extends React.Component {

    constructor(props) {
        
        super(props);

        this.state = {
            stepDataStore : props.stepDataStore,
            configItems : [],
            configValues : {},
        }
    }

    componentDidMount() {
        
        if( this.props.changeWizardState !== undefined){
            this.props.changeWizardState({
                canGoPrev : true,
                canFinish : false,
            });
        }
    }

    buildConfigForm = (dependDaoObject) => {

        const {stepDataStore,configValues} = this.state;

        ajax('PRODUCT/MODEL/productModelObject/getModelObjectRelates',{relatedObjectId:dependDaoObject.relatedObjectId,relatedType : 'MAP_DAO,DEPEND_DAO'}).then( (resultList) => {
            const objectList = [];

            objectList.push(<Option key={dependDaoObject.relatedObjectId} value={dependDaoObject.relatedObjectId}>{dependDaoObject.relatedObjectPackageName + '.' + dependDaoObject.relatedObjectName}</Option>);
            
            resultList.map( (relatedObj) => {
                objectList.push(<Option key={relatedObj.objectId} value={relatedObj.objectId}>{relatedObj.objectPackageName + '.' + relatedObj.objectName}</Option>);
            } );

            ajax("PRODUCT/MODEL/productModelObject/getModelServiceTemplateExpressionFormBean",{serviceTemplateId:stepDataStore.selectServiceTemplateIds[0]},(data) => {
                const formFields = data.formProperties.map( (item) => {
                    configValues[item.id] = 0;
                    return (
                        <React.Fragment key={item.id + 'Fragment'}>
                            <Divider key={item.id + 'Divider'} orientation="left">{item.id}</Divider>
                            <Select key={item.id} style={{ width: '100%' }} onSelect={(value) => {
                                configValues[item.id] = value;
                                this.setState({configValues : configValues});

                                stepDataStore.configValues = configValues;

                                let hasValue = true;

                                for(let configItem in configValues) {

                                   if(configValues[configItem] === 0){
                                    hasValue = false;
                                   }
                               
                                }

                                if( this.props.changeWizardState !== undefined){
                                    this.props.changeWizardState({
                                        canFinish : hasValue,
                                    });
                                }
                            }}>
                            {objectList}
                            </Select>
                        </React.Fragment>
                    );
                    
                } );
    
                this.setState({configItems : formFields});
                           
            });

        } );
    }

    render(){

        const {configItems} = this.state;

        return (
            <div style={{padding : '24px'}}>
                {configItems}
            </div>
        );
    }
}

/**
 * 服务对象代码预览
 */
const ProductServiceObjectCodePreviewPanel  = WarpModelObjectCodePreviewPanel({
    targetType : 'SERVICE',
});

/** 
 * 枚举对象Tabs
*/
const ProductEnumObjectEditTabsPanel  = WarpModelObjectEditTabPanel({
    modelObjectType : 'ENUM',
    tabConfigId: 'enumObjectTab',
    titleIcon: 'th-list',
    onTabChange: (tabName,modelObject) => {
        
        switch (tabName) {
            case 'basicInfo':
            this.enumFormRef.setModelObject(modelObject);
            break;
            case 'enumPropertyList':
            this.enumPropertyListRef.setModelObject(modelObject);
            break;
            case 'objectCodePreviewTabItem':
            this.objectCodePreviewRef.setModelObject(modelObject);
            break;
        }
    },
    getTabPanelMap: (warpedProps) => {
        return {
            '/productEnumObjectBasicInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductEnumObjectBasicInfoPanel {...warpedProps} ref={(inst) => this.enumFormRef = inst} />);
                }
            },
            '/productEnumObjectPropertyListPanel': {
                getComponent: (owner, props) => {
                    return (<ProductEnumPropertyListPanel {...warpedProps} ref={(inst) => this.enumPropertyListRef = inst} />);
                }
            },
            '/productEnumObjectCodePreviewPanel': {
                getComponent: (owner, props) => {
                    return (<ProductEnumObjectCodePreviewPanel {...warpedProps} ref={(inst) => this.objectCodePreviewRef = inst} />);
                }
            },
        }
    },
});

/**
 * 枚举对象基本信息
 */
const ProductEnumObjectBasicInfoPanel = WarpModelObjectFormPanel({ formConfigId: 'productEnumForm' });

/**
 * 枚举对象属性
 */
const ProductEnumPropertyListPanel = WarpModelPropertyListTabPanel({
    tableConfigId : 'enumObjectPropertyListTable',
    actionGroupId : 'tableFieldListActionGroup',
    rowActionGroupId : 'tableFieldRowActionGroup',
    formConfigId : 'addNewProductEnumPropertyForm',
});

/**
 * 枚举对象代码预览
 */
const ProductEnumObjectCodePreviewPanel  = WarpModelObjectCodePreviewPanel({
    targetType : 'ENUM',
});

/**
 * DTO编辑TAB页面
 */
const ProductDtoObjectEditTabsPanel  = WarpModelObjectEditTabPanel({
    modelObjectType : 'DTO',
    tabConfigId: 'dtoObjectTab',
    titleIcon: 'cube',
    onTabChange: (tabName,modelObject) => {
        
        switch (tabName) {
            case 'basicInfo':
                this.dtoFormRef.setModelObject(modelObject);
                break;
            case 'dtoPropertyList':
                this.dtoPropertyListRef.setModelObject(modelObject);
                break;
            case 'dtoMapInfo':
                this.dtoMapInfoRef.setModelObject(modelObject);
                break;
            case 'objectCodePreviewTabItem':
                this.objectCodePreviewRef.setModelObject(modelObject);
                break;
        }
    },
    getTabPanelMap: (warpedProps) => {
        return {
            '/productDtoObjectBasicInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDtoObjectBasicInfoPanel {...warpedProps} ref={(inst) => this.dtoFormRef = inst} />);
                }
            },
            '/productDtoObjectPropertyListPanel' : {
                getComponent: (owner, props) => {
                    return (<ProductDtoPropertyListPanel {...warpedProps} ref={(inst) => this.dtoPropertyListRef = inst} />);
                }
            },
            '/productDtoObjectMapInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDtoObjectMapInfoPanel {...warpedProps} ref={(inst) => this.dtoMapInfoRef = inst} />);
                }
            },
            '/productDtoObjectCodePreviewPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDtoObjectCodePreviewPanel {...warpedProps} ref={(inst) => this.objectCodePreviewRef = inst} />);
                }
            },
        }
    },
});

/**
 * DTO基本信息表单
 */
const ProductDtoObjectBasicInfoPanel = WarpModelObjectFormPanel({ formConfigId: 'productDtoForm' });

const ProductDtoPropertyListPanel = WarpModelPropertyListTabPanel({
    tableConfigId : 'dtoObjectPropertyListTable',
    actionGroupId : 'tableFieldListActionGroup',
    rowActionGroupId : 'tableFieldRowActionGroup',
    formConfigId : 'addNewProductDtoPropertyForm',
});

/**
 * DTO对象映射页面
 */
class ProductDtoObjectMapInfoPanel extends React.Component {
    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        ajax('PRODUCT/MODEL/productModelObject/getRelatedModelObject',{id :modelObject.id,relateType : "MAP_DAO"}, (data) => {
            if(data !== null && data !== undefined && this.mappedObjectFormRef !== null){
                this.relatedObject = data;
                this.mappedObjectFormRef.setFormData(data);
                this.mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : data.id});
            }
        });
        
        ajax('PRODUCT/MODEL/productModelObject/getModelObjectRelateId',{id :modelObject.id,relateType : "MAP_DAO"}, (data) => {
            if(data !== null && data !== undefined){
                this.objectRelateId = data;
            }
        });

        
    }

    actionHandler = (actionEvent) => {
        const { modelObject,relatedObject,selectRelatedIds,chooseDaoRef } = this;
        return {
            removeRelation: () => {
                ajax('PRODUCT/MODEL/productModelObject/removeRelatedModelProperties',{ids :selectRelatedIds},(data) => {
                    this.mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                });
            },
            addRelation : () => {

                const {addNewMappedFormRef} = this
                
                addNewMappedFormRef.openModal(() => {
                    addNewMappedFormRef.setFormFieldParams('propertyId',{dtoObjectId : modelObject.id});
                    addNewMappedFormRef.setFormFieldParams('relatedPropertyId',{objectId :relatedObject.id });
                });
            },
            close : () => {
                const {addNewMappedFormRef} = this;
                
                addNewMappedFormRef.closeModal();
            },
            doSave : () => {
                const {addNewMappedFormRef,mappedPropertiesRef} = this;

                addNewMappedFormRef.getFormData( (formData) => {
                    ajax('PRODUCT/MODEL/productModelObject/addRelatedModelProperty',{...formData,relatedType : 'MAP_DAO',objectRelateId : this.objectRelateId  },(data) => {
                        addNewMappedFormRef.closeModal();
                        mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                    });
                });
            },
            syncProperties : () => {
                const {mappedPropertiesRef} = this;
                ajax("PRODUCT/MODEL/productModelObject/syncDtoObject",{"dtoId" :modelObject.id},function(data){
				    if(data){
                        mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                    }
                });
            },
            mapDaoObject : () => {
                chooseDaoRef.openModal(() => {
                    chooseDaoRef.setSearchFormParams({ domainId: modelObject.domainId, packageType: 'DAO' });
                    chooseDaoRef.loadData({domainId:modelObject.domainId});
                });
            }
        }
    }

    mapDaoActionHandler = (actionEvent) => {
        const { modelObject,chooseDaoRef,selectedDaoId } = this;
        return {
            close : () => {
                chooseDaoRef.closeModal();
            },
            doSave : () => {

               ajax('PRODUCT/MODEL/productModelObject/addModelObjectRelate',{objectId : modelObject.id,mappedObjectId : selectedDaoId,mapType : 'MAP_DAO'},(data) => {
                chooseDaoRef.closeModal();
                this.setModelObject(modelObject);
               });
            }
        };
    }

    render() {

        const tableProps = {
            title : "已映射属性",
            ref : (inst) => this.mappedPropertiesRef = inst,
            tableConfigId : "modelObjectPropertyRelatedList",
            dataUrl : "PRODUCT/MODEL/productModelObject/queryRelatedModelProperties?relatedType=MAP_DAO",
            actionGroupId : "daoMappingActionGroup",
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (topToolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    topToolBar.enable('removeRelation');
                }
                else {
                    topToolBar.disable('removeRelation');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        };

        return (
            <div>
                <Row >
                    <Col span={24}>
                        <UIFormView title="映射对象" actionGroupId="dtoMapActionGroup" actionHandler={this.actionHandler} ref={(inst) => this.mappedObjectFormRef = inst} formConfigId="relatedObjectForm"/>
                    </Col>
                </Row>
                <Row style={{marginTop : '5px'}}>
                    <Col span={24}>
                        <UIDataTableView {...tableProps} />
                    </Col>
                </Row>
                <UIFormView 
                    title="新建属性映射" 
                    params={{dtoObjectId : 0,objectId : 0}} 
                    inPop={true} ref={(inst) => this.addNewMappedFormRef = inst} 
                    formConfigId="dtoMappingForm" 
                    actionGroupId="saveAndCloseActionGroup"
                    actionHandler={this.actionHandler}
                    destroyOnClose={true}
                />
                <UIDataTableView
                    bordered={false}
                    title="选择DAO对象"
                    destroyOnClose={true}
                    width={900}
                    inPop={true}
                    ref={(inst) => this.chooseDaoRef = inst}
                    tableConfigId="modelObjectList"
                    searchFormId="modelObjectSearchForm"
                    params={{domainId: 0, packageType: 'DAO'}}
                    dataUrl="PRODUCT/MODEL/productModelObject/queryModelObjects?objectType=DAO"
                    selectMode="single"
                    autoLoad={false}
                    actionGroupId="saveAndCloseActionGroup"
                    actionHandler={this.mapDaoActionHandler}
                    onSelectChange={
                        (selectRowKeys) => {
                            this.selectedDaoId = selectRowKeys[0];
                        }
                    }
                />
            </div>
        );
    }
}

/**
 * 数据包装对象代码预览
 */
const ProductDtoObjectCodePreviewPanel  = WarpModelObjectCodePreviewPanel({
    targetType : 'DTO',
});

/** 
 * DAO编辑
*/
const ProductDaoObjectEditTabsPanel = WarpModelObjectEditTabPanel({
    modelObjectType : 'DAO',
    tabConfigId: 'daoObjectTab',
    titleIcon: 'cog',
    onTabChange: (tabName,modelObject) => {
        
        switch (tabName) {
            case 'basicInfo':
            this.daoFormRef.setModelObject(modelObject);
            break;
        case 'daoMapInfo':
            this.daoMapInfoRef.setModelObject(modelObject);
            break;
        case 'daoPropertyList':
            this.daoPropertyListRef.setModelObject(modelObject);
            break;
        case 'relateQueryTabItem':
            this.relateQueryRef.setModelObject(modelObject);
            break;
        case 'relateOperationTabItem':
            this.relateOperationRef.setModelObject(modelObject);
            break;
        case 'daoActionTabItem':
            this.daoActionRef.setModelObject(modelObject);
            break;
        case 'objectUniqueTabItem':
            this.daoUniqueRef.setModelObject(modelObject);
            break;
        case 'objectRelateTabItem':
            this.objectRelateRef.setModelObject(modelObject);
            break;
        case 'objectCodePreviewTabItem':
            this.objectCodePreviewRef.setModelObject(modelObject);
            break;
        }
    },
    getTabPanelMap: (warpedProps) => {
        return {
            '/productDaoObjectFormPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectFormPanel {...warpedProps} ref={(inst) => this.daoFormRef = inst} />);
                }
            },
            '/productDaoObjectPropertyListPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectPropertyListPanel {...warpedProps} ref={(inst) => this.daoPropertyListRef = inst} />);
                }
            },
            '/productDaoObjectMapInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectMapInfoPanel {...warpedProps} ref={(inst) => this.daoMapInfoRef = inst} />);
                }
            },
            '/productDaoObjectRelateQueryPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectRelateQueryPanel {...warpedProps} ref={(inst) => this.relateQueryRef = inst} />);
                }
            },
            '/productDaoObjectRelateOperationPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectRelateOperationPanel {...warpedProps} ref={(inst) => this.relateOperationRef = inst} />);
                }
            },
            '/productDaoObjectActionPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectActionPanel {...warpedProps} ref={(inst) => this.daoActionRef = inst} />);
                }
            },
            '/productDaoObjectUniqueInfoPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectUniqueInfoPanel {...warpedProps} ref={(inst) => this.daoUniqueRef = inst} />);
                }
            },
            '/productDaoObjectRelatedPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectRelatedPanel {...warpedProps} ref={(inst) => this.objectRelateRef = inst} />);
                }
            },
            '/productDaoObjectCodePreviewPanel': {
                getComponent: (owner, props) => {
                    return (<ProductDaoObjectCodePreviewPanel {...warpedProps} ref={(inst) => this.objectCodePreviewRef = inst} />);
                }
            },
        }
    },
});

/**
 * DAO基本信息表单
 */
const ProductDaoObjectFormPanel = WarpModelObjectFormPanel({ formConfigId: 'productDaoObjectForm' });

/**
 * DAO属性列表
 */
const ProductDaoObjectPropertyListPanel = WarpModelPropertyListTabPanel({
    tableConfigId : 'daoObjectPropertyList',
    actionGroupId : 'tableFieldListActionGroup',
    rowActionGroupId : 'tableFieldRowActionGroup',
    formConfigId : 'addNewDaoPropertyForm',
});


/**
 * DAO对象与表对象映射信息
 */
class ProductDaoObjectMapInfoPanel extends React.Component {

    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        ajax('PRODUCT/MODEL/productModelObject/getRelatedModelObject',{id :modelObject.id,relateType : "MAP_TABLE"}, (data) => {
            if(data !== null && data !== undefined && this.mappedObjectFormRef !== null){
                this.relatedObject = data;
                this.mappedObjectFormRef.setFormData(data);
                this.mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : data.id});
            }
        });
        
        ajax('PRODUCT/MODEL/productModelObject/getModelObjectRelateId',{id :modelObject.id,relateType : "MAP_TABLE"}, (data) => {
            if(data !== null && data !== undefined){
                this.objectRelateId = data;
            }
        });

        
    }

    actionHandler = (actionEvent) => {
        const { modelObject,relatedObject,selectRelatedIds } = this;
        return {
            removeRelation: () => {
                ajax('PRODUCT/MODEL/productModelObject/removeRelatedModelProperties',{ids :selectRelatedIds},(data) => {
                    this.mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                });
            },
            addRelation : () => {

                const {addNewMappedFormRef} = this
                
                addNewMappedFormRef.openModal(() => {
                    addNewMappedFormRef.setFormFieldParams('propertyId',{daoObjectId : modelObject.id});
                    addNewMappedFormRef.setFormFieldParams('relatedPropertyId',{objectId :relatedObject.id });
                });
            },
            close : () => {
                const {addNewMappedFormRef} = this;
                
                addNewMappedFormRef.closeModal();
            },
            doSave : () => {
                const {addNewMappedFormRef,mappedPropertiesRef} = this;

                addNewMappedFormRef.getFormData( (formData) => {
                    ajax('PRODUCT/MODEL/productModelObject/addRelatedModelProperty',{...formData,relatedType : 'MAP_TABLE',objectRelateId : this.objectRelateId  },(data) => {
                        addNewMappedFormRef.closeModal();
                        mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                    });
                });
            },
            syncProperties : () => {
                const {mappedPropertiesRef} = this;
                ajax("PRODUCT/MODEL/productModelObject/syncDaoObject",{"daoId" :modelObject.id},function(data){
				    if(data){
                        mappedPropertiesRef.loadData({objectId:modelObject.id,relatedObjectId : relatedObject.id});
                    }
                });
            },
        }
    }

    render() {

        const tableProps = {
            title : "已映射属性",
            ref : (inst) => this.mappedPropertiesRef = inst,
            tableConfigId : "modelObjectPropertyRelatedList",
            dataUrl : "PRODUCT/MODEL/productModelObject/queryRelatedModelProperties?relatedType=MAP_TABLE",
            actionGroupId : "daoMappingActionGroup",
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (topToolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    topToolBar.enable('removeRelation');
                }
                else {
                    topToolBar.disable('removeRelation');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        };

        return (
            <div>
                <Row >
                    <Col span={24}>
                        <UIFormView title="映射对象" ref={(inst) => this.mappedObjectFormRef = inst} formConfigId="relatedObjectForm"/>
                    </Col>
                </Row>
                <Row style={{marginTop : '5px'}}>
                    <Col span={24}>
                        <UIDataTableView {...tableProps} />
                    </Col>
                </Row>
                <UIFormView 
                    title="新建属性映射" 
                    params={{daoObjectId : 0,objectId : 0}} 
                    inPop={true} ref={(inst) => this.addNewMappedFormRef = inst} 
                    formConfigId="daoMappingForm" 
                    actionGroupId="saveAndCloseActionGroup"
                    actionHandler={this.actionHandler}
                    destroyOnClose={true}
                />
            </div>
        );
    }
}

/**
 * DAO关联查询配置
 */
class ProductDaoObjectRelateQueryPanel extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            stepDataStore: {},
        }
    }

    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        this.daoRelateQueryListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_QUERY"});
    }

    actionHandler = (actionEvent) => {
        const { modelObject,selectRelatedIds,daoRelateQueryListRef } = this;
        return {
            removeRelation : () => {
               
                const selectedIds = actionEvent.params !== undefined ? [actionEvent.params.id] : selectRelatedIds;
                ajax('PRODUCT/MODEL/productModelObject/removeRelatedModelObjects',{ids : selectedIds},(data) => {
                    daoRelateQueryListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_QUERY"});
                });
            },
            addRelation : () => {
                this.addNewRelatedQueryRef.openModal();
            },
            editRelation : () => {

                ajax('PRODUCT/MODEL/productModelObject/getRelatedProperties',{relationId : actionEvent.params.id},(data) => {

                    const relatedQueryKeyList = [];

                    const relatedQueryList = [];

                    data.map(relatedItem => {
                        if(relatedItem.relatedConfig === "RELATE_KEY"){
                            relatedQueryKeyList.push(relatedItem);
                        }
                        else{
                            relatedQueryList.push(relatedItem);
                        }
                    });

                    this.setState({ stepDataStore : {
                        id : actionEvent.params.id,
                        relatedQueryKeyList : relatedQueryKeyList,
                        relatedQueryList : relatedQueryList,
                        daoId : actionEvent.params.objectId,
                        selectedDaoId : [actionEvent.params.relatedObjectId],
                        relatedConfig : {relateName : actionEvent.params.relateName, relatedConfig : actionEvent.params.relatedConfig}
                    } });

                    setTimeout(() => {
                        this.editRelatedQueryRef.openModal();
                    });
                   
                });
                
            },
            moveUp : () =>{
		
                const objectRelateIds = [];
                
                const records = daoRelateQueryListRef.getListData();
                
                for (let i = 0; i < records.length; i++) {
                    objectRelateIds.push(records[i].id);
                }
                
                const index = objectRelateIds.indexOf(selectRelatedIds[0]);
                
                if(index == 0){
                    return;
                }
                
                objectRelateIds[index] = objectRelateIds.splice(index - 1, 1, objectRelateIds[index])[0];
                
                ajax('PRODUCT/MODEL/productModelObject/setModelObjectRelationSort',{objectRelateIds :objectRelateIds},(data) => {
                    daoRelateQueryListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_QUERY"});
                });
            },
            moveDown : () => {
                
                const objectRelateIds = [];
                
                const records = daoRelateQueryListRef.getListData();
                
                for (let i = 0; i < records.length; i++) {
                    objectRelateIds.push(records[i].id);
                }
                
                const index = objectRelateIds.indexOf(selectRelatedIds[0]);
                
                if(index === objectRelateIds.length - 1){
                    return;
                }
                
                objectRelateIds[index] = objectRelateIds.splice(index + 1, 1, objectRelateIds[index])[0];

                ajax('PRODUCT/MODEL/productModelObject/setModelObjectRelationSort',{objectRelateIds :objectRelateIds},(data) => {
                    daoRelateQueryListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_QUERY"});
                });
                
            },
            doSave : () => {
                
                const relatedStore = this.state.stepDataStore;

                this.onWizardFinish(relatedStore);
            },
        }
    }

    onWizardStepChange = (wizardStepId) => {
        
        if('chooseRelatedDaoObject' === wizardStepId){
            this.selectRelatedDaoObject = this.chooseDaoRef.getSelectedDaoObject()[0];
        }
    }

    onInitWizardStep  = (wizardStepId) => {
        
        if('configPKRelated' === wizardStepId && this.configRelateQueryKeyRef !== null){
            this.configRelateQueryKeyRef.setRelateData(this.modelObject,this.selectRelatedDaoObject);
        }
        if('configDisplayRelated' === wizardStepId && this.configRelateQueryDisplayRef !== null){
            this.configRelateQueryDisplayRef.setRelateData(this.modelObject,this.selectRelatedDaoObject);
        }
    }

    onWizardFinish = (wizardDataStore) => {
        
        const id = wizardDataStore.id !== undefined ? wizardDataStore.id : 0;

        const modelObjectId = this.modelObject.id;

        const relatedObjId = wizardDataStore.selectedDaoId[0];
		const keyRecords = wizardDataStore.relatedQueryKeyList;
		const queryRecords = wizardDataStore.relatedQueryList;
		const relatConfigData = wizardDataStore.relatedConfig;
		const propertyIds = [];
			
		const relatedPropertyIds = [];
			
		for(let i = 0;i< keyRecords.length;i++){
		    propertyIds.push(keyRecords[i].propertyId);
		    relatedPropertyIds.push(keyRecords[i].relatedPropertyId);
		}
			
		for(let i = 0;i< queryRecords.length;i++){
			propertyIds.push(queryRecords[i].propertyId);
			relatedPropertyIds.push(queryRecords[i].relatedPropertyId);
        }
        
        ajax('PRODUCT/MODEL/productModelObject/setProductModelObjectRelated',{
            id:id,
            objectId : modelObjectId,
            relatedObjectId:relatedObjId,
            relateName:relatConfigData.relateName,
            relatedConfig:relatConfigData.relatedConfig,
            keyPropertyLength:keyRecords.length,
            propertyIds:propertyIds,
            relatedPropertyIds:relatedPropertyIds,
            relateType : "RELATE_QUERY"
        },(data) => {
            if(this.addNewRelatedQueryRef !== undefined){
                this.addNewRelatedQueryRef.closeModal();
            }
            if(this.editRelatedQueryRef !== undefined){
                this.editRelatedQueryRef.closeModal();
            }
            this.daoRelateQueryListRef.loadData({objectId : modelObjectId,relatedType : "RELATE_QUERY"});
        });
		
    }

    render() {

        const tableProp = {
            bordered : false,
            ref : (inst) => this.daoRelateQueryListRef = inst,
            tableConfigId : "modelObjectRelatedQueryList",
            dataUrl : "PRODUCT/MODEL/productModelObject/queryModelObjectRelates",
            actionGroupId : "daoRelatedQueryActionGroup",
            rowActionGroupId : "daoRelatedQueryRowActionGroup",
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (toolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    toolBar.enable('removeRelation');
                    toolBar.enable('editRelation');
                    toolBar.enable('moveUp');
                    toolBar.enable('moveDown');
                }
                else {
                    toolBar.disable('removeRelation');
                    toolBar.disable('editRelation');
                    toolBar.disable('moveUp');
                    toolBar.disable('moveDown');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        };

        const tabPanelMap = {
            '/ChooseDAOObjectPanel': {
                getComponent: (owner, props) => {
                    return (<ChooseDaoObjectPanel {...this.props} {...props} ref={(inst) => this.chooseDaoRef = inst} />);
                }
            },
            '/ConfigDAORelatedKeyPanel': {
                getComponent: (owner, props) => {
                    return (<ConfigDaoRelatedKeyPanel {...this.props} {...props} relatedType="RELATE_QUERY" ref={(inst) => this.configRelateQueryKeyRef = inst} />);
                }
            },
            '/ConfigDAORelatedQueryDisplayPanel': {
                getComponent: (owner, props) => {
                    return (<ConfigDaoRelatedQueryDisplayPanel {...this.props} {...props} ref={(inst) => this.configRelateQueryDisplayRef = inst} />);
                }
            },
            
        }

        return (
            <React.Fragment>
                <UIDataTableView {...tableProp}/>
                <UIView title="新增关联查询" destroyOnClose={true} width={900} inPop={true} ref={ (inst) => this.addNewRelatedQueryRef = inst }>
                    <UIWizard 
                        tabConfigId="addNewDaoRelatedQueryWizard" 
                        tabContentMap={tabPanelMap}
                        canGoNext={false}
                        onWizardStepChange={this.onWizardStepChange}
                        onInitWizardStep={this.onInitWizardStep}
                        onWizardFinish={this.onWizardFinish}
                    />
                </UIView>
                <UITabsView 
                    actionGroupId="saveActionGroup"
                    actionHandler={this.actionHandler}
                    stepDataStore={this.state.stepDataStore}
                    destroyOnClose={true}
                    width={900}
                    tabConfigId="daoRelatedQueryConfigTab"
                    tabContentMap={tabPanelMap}
                    inPop={true}
                    title="配置关联查询"
                    ref={ (inst) => this.editRelatedQueryRef = inst }
                />
            </React.Fragment>
        );
    }
}

/**
 * 选择DAO对象
 */
class ChooseDaoObjectPanel  extends React.Component {

    constructor(props) {
        
        super(props);
        this.state = {
            stepDataStore : props.stepDataStore,
        }
    }

    componentDidMount() {
        const {stepDataStore} = this.state;

        if( this.props.changeWizardState !== undefined){
            this.props.changeWizardState({
                canGoNext : false,
                canGoPrev : false,
                canFinish : false,
            });
        }

        if(stepDataStore !== undefined ){
            this.chooseDaoRef.setSelected(stepDataStore.selectedDaoId);
        }
    }

    getSelectedDaoObject = () => {
        return this.chooseDaoRef.getSelectedDatas();
    }

    render() {
        const {stepDataStore} = this.state;

        return (
            <React.Fragment>
            <UIDataTableView 
                bordered={false}
                ref={ (inst) => this.chooseDaoRef = inst }
                tableConfigId="modelObjectList"
                searchFormId="modelObjectWithDomainSearchForm"
                dataUrl="PRODUCT/MODEL/productModelObject/queryModelObjects?objectType=DAO"
                selectMode="single"
                autoLoad={true}
                onSelectChange={
                    (selectRowKeys) => {
                        
                        if( this.props.changeWizardState !== undefined){
                            this.props.changeWizardState({
                                canGoNext : selectRowKeys !== undefined ? true : false,
                                canGoPrev : false,
                                canFinish : false,
                                //stepDataStore 
                            });
                        }

                        if(stepDataStore !== undefined ){
                            stepDataStore.selectedDaoId = selectRowKeys;
                        }
                    }
                }
            />
            </React.Fragment>
        );
    }
}

/**
 * 配置DAO关联查询-关联条件
 */
class ConfigDaoRelatedKeyPanel  extends React.Component {

    constructor(props) {
        
        super(props);
        this.state = {
            stepDataStore : props.stepDataStore,
        }
    }

    componentDidMount() {
        const {stepDataStore} = this.state;

        if(stepDataStore !== undefined ){
           
            this.relatedPropertiesRef.setListData(stepDataStore.relatedQueryKeyList);

            if(stepDataStore.relatedConfig !== undefined ){
                this.relateConfigFormRef.setFormData(stepDataStore.relatedConfig);
            }

            if(stepDataStore.daoId !== undefined ){
                this.relateKeyFormRef.setFormFieldParams('propertyId',{objectId :stepDataStore.daoId });
            }
            
            if(stepDataStore.selectedDaoId !== undefined ){
                this.relateKeyFormRef.setFormFieldParams('relatedPropertyId',{objectId :stepDataStore.selectedDaoId[0] });
            }

            if( this.props.changeWizardState !== undefined){
                this.props.changeWizardState({
                    canGoNext : false,
                    canGoPrev : true,
                    canFinish : false,
                    //stepDataStore 
                });
            }
            
        }
    }

    setRelateData = (daoObj,relatedDaoObj) => {
        
        const {stepDataStore} = this.state;

        if(stepDataStore.selectedDaoId !== undefined && stepDataStore.selectedDaoId[0] !== relatedDaoObj.id){
            this.relatedPropertiesRef.setListData([]);
        }

        this.setState({daoObj : daoObj,relatedDaoObj : relatedDaoObj});
        this.relateKeyFormRef.setFormFieldParams('propertyId',{objectId :daoObj.id });
        this.relateKeyFormRef.setFormFieldParams('relatedPropertyId',{objectId :relatedDaoObj.id });

        this.relateConfigFormRef.setFormData({
            relateName : 'RELATED_' + randomString(6) + '_' + relatedDaoObj.objectName,
            relatedConfig : 'LEFT',
        });
    }

    onValuesChange = (values) => {
        const {stepDataStore} = this.state;
        stepDataStore.relatedConfig = {...stepDataStore.relatedConfig,...values}
    }

    actionHandler = (actionEvent) => {
        
        const {stepDataStore} = this.state;

        return {
            removeRelation : () => {

                const listData = this.relatedPropertiesRef.getListData();

                let newArray = [];

                listData.map( (dataItem) => {
                    if(inArray(dataItem.id,this.selectRelatedIds) === -1){
                        newArray.push(dataItem);
                    }
                } );

                this.relatedPropertiesRef.setListData(newArray);

                stepDataStore.relatedQueryKeyList = newArray;

                if( this.props.changeWizardState !== undefined){
                    this.props.changeWizardState({
                        canGoNext : newArray.length > 0,
                        canGoPrev : true,
                        canFinish : false,
                        //stepDataStore 
                    });
                }
            },
            addRelation : () => {
                this.relateKeyFormRef.getFormData((formData) => {

                    const relatedList = this.relatedPropertiesRef.getListData();

                    if(relatedList !== undefined){

                        let hadAdded = false;

                        relatedList.map( (relateItem) => {
                            if(formData.propertyId === relateItem.propertyId && formData.relatedPropertyId === relateItem.relatedPropertyId){
                                hadAdded = true;
                            }
                        } );

                        if(hadAdded === true){
                            message.error('属性已经关联，不能重复关联');
                            return;
                        }
                    }
                   
                    batchAjax(
                        ['PRODUCT/MODEL/productModelObject/getModelPropertyById','PRODUCT/MODEL/productModelObject/getModelPropertyById'],
                        [{propertyId : formData.propertyId},{propertyId : formData.relatedPropertyId}],
                        (results) => {
                        
                            let listData = this.relatedPropertiesRef.getListData();

                            if(listData === null || listData === undefined){
                                listData = [];
                            }
                            
                            const rowId = listData.length === 0 ? listData.length + 1 : listData[listData.length -1].id + 1;

                            const propertyName = results[0].propertyName;

                            const relatedPropertyName = results[1].propertyName;

                            listData.push({
                                id: rowId,
                                propertyName: propertyName,
                                relatedPropertyName: relatedPropertyName,
                                propertyId : formData.propertyId,
                                relatedPropertyId: formData.relatedPropertyId,
                                relatedType: this.props.relatedType,
                                relatedConfig: 'RELATE_KEY',
                            });

                            stepDataStore.relatedQueryKeyList = listData;

                            this.relateConfigFormRef.getFormData(formData => {
                                stepDataStore.relatedConfig = formData;
                            })

                            this.relatedPropertiesRef.setListData(listData);

                            if( this.props.changeWizardState !== undefined){
                                this.props.changeWizardState({
                                    canGoNext : true,
                                    canGoPrev : true,
                                    canFinish : false,
                                    //stepDataStore 
                                });
                            }
                           
                        }
                    );
                })
            }
        }

    }
    
    render() {

        const tableProps = {
            bordered : false,
            tableConfigId : 'modelObjectPropertyRelatedList',
            actionGroupId : 'daoRelateActionGroup',
            ref : (inst) => {
                this.relatedPropertiesRef = inst;
            },
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (toolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    toolBar.enable('removeRelation');
                }
                else {
                    toolBar.disable('removeRelation');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        };

        return (
            <React.Fragment>
                <Row >
                    <Col span={24}>
                        <Divider orientation="left">关联配置</Divider>
                        <UIForm wrappedComponentRef={(inst) => this.relateConfigFormRef = inst} formConfigId="objectRelatedConfigForm" onValuesChange={this.onValuesChange}/>
                    </Col>
                </Row>
                <Row >
                    <Col span={24}>
                        <Divider orientation="left">选择关联条件</Divider>
                        <UIForm actionGroupId="daoRelatePropertyActionGroup" actionHandler={this.actionHandler} params={{objectId : 0}} wrappedComponentRef={(inst) => this.relateKeyFormRef = inst} formConfigId="objectRelatedForm"/>
                    </Col>
                </Row>
                <Row >
                    <Col span={24}>
                        <Divider orientation="left">已关联条件属性</Divider>
                        <UIDataTableView {...tableProps} />
                    </Col>
                </Row>
            </React.Fragment>
        );
    }
}

/**
 * 关联查询配置
 */
class ConfigDaoRelatedQueryDisplayPanel  extends React.Component {

    constructor(props) {
        
        super(props);
        this.state = {
            stepDataStore : props.stepDataStore,
        }
    }

    componentDidMount() {
        const {stepDataStore} = this.state;

        if(stepDataStore !== undefined ){
           
            this.relatedPropertiesRef.setListData(stepDataStore.relatedQueryList);

            if(stepDataStore.daoId !== undefined ){
                this.relateQueryFormRef.setFormFieldParams('propertyId',{objectId :stepDataStore.daoId });
            }
            
            if(stepDataStore.selectedDaoId !== undefined ){
                this.relateQueryFormRef.setFormFieldParams('relatedPropertyId',{objectId :stepDataStore.selectedDaoId[0] });
            }

            if( this.props.changeWizardState !== undefined){
                this.props.changeWizardState({
                    canGoNext : false,
                    canGoPrev : true,
                    canFinish : false,
                    //stepDataStore 
                });
            }
        }
    }

    setRelateData = (daoObj,relatedDaoObj) => {
        
        const {stepDataStore} = this.state;

        if(stepDataStore.selectedDaoId !== undefined && stepDataStore.selectedDaoId[0] !== relatedDaoObj.id){
            this.relatedPropertiesRef.setListData([]);
        }

        this.setState({daoObj : daoObj,relatedDaoObj : relatedDaoObj});
        this.relateQueryFormRef.setFormFieldParams('propertyId',{objectId :daoObj.id,relatedType : 'MAP_TABLE,RELATE_QUERY' });
        this.relateQueryFormRef.setFormFieldParams('relatedPropertyId',{objectId :relatedDaoObj.id });

    }

    actionHandler = (actionEvent) => {
        
        const {stepDataStore} = this.state;

        return {
            removeRelation : () => {

                const listData = this.relatedPropertiesRef.getListData();

                let newArray = [];

                let addOptionItems = [];

                listData.map( (dataItem) => {
                    if(inArray(dataItem.id,this.selectRelatedIds) === -1){
                        newArray.push(dataItem);
                    }
                    else{
                        addOptionItems.push(
                            <Option key={dataItem.propertyId} value={dataItem.propertyId}>{dataItem.propertyName}</Option>
                        );
                    }
                    
                } );

                this.relateQueryFormRef.addFormFieldOptionItems('propertyId',addOptionItems);

                this.relatedPropertiesRef.setListData(newArray);

                stepDataStore.relatedQueryList = newArray;

                if( this.props.changeWizardState !== undefined){
                    this.props.changeWizardState({
                        canGoNext : false,
                        canGoPrev : true,
                        canFinish : newArray.length > 0,
                        //stepDataStore 
                    });
                }
            },
            addRelation : () => {

                this.relateQueryFormRef.getFormData((formData) => {

                    const relatedList = this.relatedPropertiesRef.getListData();

                    if(relatedList !== undefined){

                        let hadAdded = false;

                        relatedList.map( (relateItem) => {
                            if(formData.propertyId === relateItem.propertyId){
                                hadAdded = true;
                            }
                        } );

                        if(hadAdded === true){
                            message.error('属性已经关联，不能重复关联');
                            return;
                        }
                    }
                   
                    batchAjax(
                        ['PRODUCT/MODEL/productModelObject/getModelPropertyById','PRODUCT/MODEL/productModelObject/getModelPropertyById'],
                        [{propertyId : formData.propertyId},{propertyId : formData.relatedPropertyId}],
                        (results) => {
                        
                            let listData = this.relatedPropertiesRef.getListData();

                            if(listData === null || listData === undefined){
                                listData = [];
                            }

                            const removeOptionValues = [];
                            
                            const rowId = listData.length + 1;

                            const propertyName = results[0].propertyName;

                            const relatedPropertyName = results[1].propertyName;

                            listData.push({
                                id: rowId,
                                propertyId : formData.propertyId,
                                relatedPropertyId: formData.relatedPropertyId,
                                propertyName: propertyName,
                                relatedPropertyName: relatedPropertyName,
                                relatedType: 'RELATE_QUERY'
                            });

                            removeOptionValues.push(formData.propertyId);

                            stepDataStore.relatedQueryList = listData;

                            this.relateQueryFormRef.resetForm();

                            this.relateQueryFormRef.removeFormFieldOptionItems('propertyId',removeOptionValues);

                            this.relatedPropertiesRef.setListData(listData);

                            if( this.props.changeWizardState !== undefined){
                                this.props.changeWizardState({
                                    canGoNext : false,
                                    canGoPrev : true,
                                    canFinish : true,
                                    //stepDataStore 
                                });
                            }
                           
                        }
                    );
                })
            }
        }

    }

    render() {

        const tableProps = {
            bordered : false,
            tableConfigId : 'modelObjectPropertyRelatedList',
            actionGroupId : 'daoRelateActionGroup',
            ref : (inst) => {
                this.relatedPropertiesRef = inst;
            },
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (toolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    toolBar.enable('removeRelation');
                }
                else {
                    toolBar.disable('removeRelation');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        };

        return (
            <React.Fragment>
                <Row style={{marginTop : '5px'}}>
                    <Col span={24}>
                        <Divider orientation="left">选择关联查询</Divider>
                        <UIForm actionGroupId="daoRelatePropertyActionGroup" actionHandler={this.actionHandler} params={{objectId : 0}} wrappedComponentRef={(inst) => this.relateQueryFormRef = inst} formConfigId="objectRelatedQueryForm"/>
                    </Col>
                </Row>
                <Row style={{marginTop : '5px'}}>
                    <Col span={24}>
                        <Divider orientation="left">已关联查询属性</Divider>
                        <UIDataTableView {...tableProps} />
                    </Col>
                </Row>
            </React.Fragment>
        );
    }
}

class ProductDaoObjectRelateOperationPanel extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            stepDataStore: {},
        }
    }

    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        this.daoRelateOperationListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_OPERATION"});
    }

    actionHandler = (actionEvent) => {
        const { modelObject,selectRelatedIds,daoRelateOperationListRef } = this;
        return {
            removeRelation : () => {
               
                const selectedIds = actionEvent.params !== undefined ? [actionEvent.params.id] : selectRelatedIds;
                ajax('PRODUCT/MODEL/productModelObject/removeRelatedModelObjects',{ids : selectedIds},(data) => {
                    daoRelateOperationListRef.loadData({objectId :modelObject.id,relatedType : "RELATE_OPERATION"});
                });
            },
            addRelation : () => {
                this.addNewRelatedOperationRef.openModal();
            },
            editRelation : () => {
                ajax('PRODUCT/MODEL/productModelObject/getRelatedProperties',{relationId : actionEvent.params.id},(data) => {

                    this.setState({ stepDataStore : {
                        id : actionEvent.params.id,
                        relatedQueryKeyList : data,
                        daoId : actionEvent.params.objectId,
                        selectedDaoId : [actionEvent.params.relatedObjectId],
                        relatedConfig : {relateName : actionEvent.params.relateName, relatedConfig : actionEvent.params.relatedConfig}
                    } });

                    setTimeout(() => {
                        this.editRelatedOperationRef.openModal();
                    });
                   
                });
            },
            doSave : () => {
                const relatedStore = this.state.stepDataStore;

                this.onWizardFinish(relatedStore);
            }
        }
    }

    onWizardStepChange = (wizardStepId) => {
        
        if('chooseRelatedDaoObject' === wizardStepId){
            this.selectRelatedDaoObject = this.chooseDaoRef.getSelectedDaoObject()[0];
        }
    }

    onInitWizardStep  = (wizardStepId) => {
        
        if('configPKRelated' === wizardStepId && this.configRelateQueryKeyRef !== null){
            this.configRelateQueryKeyRef.setRelateData(this.modelObject,this.selectRelatedDaoObject);
        }
    }

    onWizardFinish = (wizardDataStore) => {
        
        const id = wizardDataStore.id !== undefined ? wizardDataStore.id : 0;

        const modelObjectId = this.modelObject.id;

        const relatedObjId = wizardDataStore.selectedDaoId[0];
		const keyRecords = wizardDataStore.relatedQueryKeyList;
		const relatConfigData = wizardDataStore.relatedConfig;
		const propertyIds = [];
			
		const relatedPropertyIds = [];
			
		for(let i = 0;i< keyRecords.length;i++){
		    propertyIds.push(keyRecords[i].propertyId);
		    relatedPropertyIds.push(keyRecords[i].relatedPropertyId);
		}
        
        ajax('PRODUCT/MODEL/productModelObject/setProductModelObjectRelated',{
            id:id,
            objectId : modelObjectId,
            relatedObjectId:relatedObjId,
            relateName:relatConfigData.relateName,
            relatedConfig:relatConfigData.relatedConfig,
            keyPropertyLength:keyRecords.length,
            propertyIds:propertyIds,
            relatedPropertyIds:relatedPropertyIds,
            relateType : "RELATE_OPERATION"
        },(data) => {
            if(this.addNewRelatedOperationRef !== undefined){
                this.addNewRelatedOperationRef.closeModal();
            }
            if(this.editRelatedOperationRef !== undefined){
                this.editRelatedOperationRef.closeModal();
            }
            this.daoRelateOperationListRef.loadData({objectId : modelObjectId,relatedType : "RELATE_OPERATION"});
        });
		
    }

    render() {

        const tableProp = {
            bordered : false,
            ref : (inst) => this.daoRelateOperationListRef = inst,
            tableConfigId : "modelObjectRelatedList",
            dataUrl : "PRODUCT/MODEL/productModelObject/queryModelObjectRelates",
            actionGroupId : "daoRelatedOperationActionGroup",
            rowActionGroupId : "daoRelatedOperationRowActionGroup",
            selectMode : "multi",
            autoLoad : false,
            setToolbarState: (toolBar, selectIds) => {
                if (selectIds !== null && selectIds.length > 0) {
                    toolBar.enable('removeRelation');
                    toolBar.enable('editRelation');
                }
                else {
                    toolBar.disable('removeRelation');
                    toolBar.disable('editRelation');
                }
            },
            actionHandler: this.actionHandler,
            onSelectChange: (selectRowKeys) => {
                this.selectRelatedIds = selectRowKeys;
            }
        }

        const tabPanelMap = {
            '/ChooseDAOObjectPanel': {
                getComponent: (owner, props) => {
                    return (<ChooseDaoObjectPanel {...this.props} {...props} ref={(inst) => this.chooseDaoRef = inst} />);
                }
            },
            '/ConfigDAORelatedKeyPanel': {
                getComponent: (owner, props) => {
                    return (<ConfigDaoRelatedKeyPanel {...this.props} {...props} relatedType="RELATE_OPERATION" ref={(inst) => this.configRelateQueryKeyRef = inst} />);
                }
            },
            
            
        }

        return (
            <React.Fragment>
                <UIDataTableView {...tableProp}/>
                
                <UIView title="新增关联操作" destroyOnClose={true} width={900} inPop={true} ref={ (inst) => this.addNewRelatedOperationRef = inst }>
                    <UIWizard 
                        tabConfigId="addNewDaoRelatedOperationWizard" 
                        tabContentMap={tabPanelMap}
                        canGoNext={false}
                        onWizardStepChange={this.onWizardStepChange}
                        onInitWizardStep={this.onInitWizardStep}
                        onWizardFinish={this.onWizardFinish}
                    />
                </UIView>
                <UITabsView 
                    actionGroupId="saveActionGroup"
                    actionHandler={this.actionHandler}
                    stepDataStore={this.state.stepDataStore}
                    destroyOnClose={true}
                    width={900}
                    tabConfigId="daoRelatedOperationConfigTab"
                    tabContentMap={tabPanelMap}
                    inPop={true}
                    title="配置关联操作"
                    ref={ (inst) => this.editRelatedOperationRef = inst }
                />
            </React.Fragment>
        );
    }
}

class ProductDaoObjectActionPanel extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            formTitle: '',
        }
    }

    setModelObject = (modelObject) => {
        
        this.modelObject = modelObject;
        this.daoActionListRef.loadData({objectId : modelObject.id});
        
    }

    actionHandler = (actionEvent) => {
        const { modelObject,selectActionIds,daoActionListRef,actionFormRef } = this;
        return {
            refresh : () => {
                daoActionListRef.loadData({objectId : modelObject.id});
            },
            addNew : () => {
                const {actionFormRef,modelObject} = this;
                this.setState({formTitle : '新增对象触发操作'});
                actionFormRef.openModal(() => {
                    actionFormRef.setFormFieldParams('propertyId',{objectId : modelObject.id});
                });
            },
            doSave : () => {
                actionFormRef.getFormData( (formData) => {
                    formData.objectId = modelObject.id;
                    ajax('PRODUCT/MODEL/productModelObject/saveModelAction',formData,(data) => {
                        actionFormRef.closeModal();
                        daoActionListRef.loadData({objectId : modelObject.id});
                    });
                } );
            },
            doEdit : () => {
                this.setState({ formTitle: '编辑对象触发操作' });
                setTimeout(() => {
                    actionFormRef.openModal(() => {
                        actionFormRef.setFormFieldParams('propertyId',{objectId : modelObject.id});
                        actionFormRef.setFormData(actionEvent.params);
                    });
                });
            },
            doDelete : () => {
               
                const selectedIds = actionEvent.params !== undefined ? [actionEvent.params.id] : selectActionIds;
                ajax('PRODUCT/MODEL/productModelObject/deleteModelActions',{ids : selectedIds},(data) => {
                    daoActionListRef.loadData({objectId : modelObject.id});
                });
            },
        }
    }

    render() {
        const daoActionTableProps = {
            ref: (inst) => { this.daoActionListRef = inst },
            tableConfigId: 'productModelActionListTable',
            dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelObjectActions',
            autoLoad: false,
            selectMode: 'multi',
            bordered: false,
            actionGroupId: 'daoActionActionGroup',
            rowActionGroupId: 'daoActionRowActionGroup',
            actionHandler: this.actionHandler,
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    topToolBar.enable('delete');
                    topToolBar.enable('edit');
                }
                else {
                    topToolBar.disable('delete');
                    topToolBar.disable('edit');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectActionIds = selectRowKeys;
                }
            ,
        };

        const formProps = {
            ref: (inst) => { this.actionFormRef = inst },
            formConfigId: 'productModelActionForm',
            actionGroupId: 'saveActionGroup',
            actionHandler: this.actionHandler,
            inPop: true,
            destroyOnClose: true,
            title: this.state.formTitle,
            params : {objectId : 0}
        }

        return (
            <UIDataTableView {...daoActionTableProps} {...this.props}>
                <UIFormView {...formProps} />
            </UIDataTableView>
        );
    }
}

class ProductDaoObjectUniqueInfoPanel extends React.Component {

    setModelObject = (modelObject) => {
        this.modelObject = modelObject;
        ajax('PRODUCT/MODEL/productModelObject/getModelRelatedPropertiesByType?isPrimaryKey=false&relateType=MAP_TABLE',{id : modelObject.id},(data) => {
            this.daoUniqueListRef.setListData(data);
        });
    }

    actionHandler = (actionEvent) => {
        const { modelObject,selectIds,daoUniqueListRef } = this;
        return {
            setDaoUnique : () => {
                ajax('PRODUCT/MODEL/productModelObject/setModelObjectUnique',{objectId : modelObject.id,propertyIds : selectIds}).then((data => {
                    ajax('PRODUCT/MODEL/productModelObject/getModelRelatedPropertiesByType?isPrimaryKey=false&relateType=MAP_TABLE',{id : modelObject.id},(data) => {
                        daoUniqueListRef.setListData(data);
                    });
                }));
            },
        }
    }

    render() {

        const daoUniqueTableProps = {
            ref: (inst) => { this.daoUniqueListRef = inst },
            tableConfigId: 'modelObjectUniquePropertyList',
            //dataUrl: 'PRODUCT/MODEL/productModelObject/getModelRelatedPropertiesByType?isPrimaryKey=false&relateType=MAP_TABLE',
            autoLoad: false,
            selectMode: 'multi',
            bordered: false,
            actionGroupId: 'daoUniqueActionGroup',
            actionHandler: this.actionHandler,
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    //topToolBar.enable('setDaoUnique');
                }
                else {
                    //topToolBar.disable('setDaoUnique');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectIds = selectRowKeys;
                }
            ,
        };

        return (
            <UIDataTableView {...daoUniqueTableProps} {...this.props}>
               
            </UIDataTableView>
        );
    }
}

class ProductDaoObjectRelatedPanel extends React.Component {

    setModelObject = (modelObject) => {
        //this.tableFormRef.setFormData(modelObject);
        console.log(modelObject);
        this.daoReltedListRef.loadData({relatedObjectId : modelObject.id});
    }

    render() {

        const tableProps = {
            ref: (inst) => { this.daoReltedListRef = inst },
            tableConfigId: 'modelObjectRefrencedList',
            dataUrl: 'PRODUCT/MODEL/productModelObject/queryModelObjectRelates',
            autoLoad: false,
            selectMode: 'none',
            bordered: false,
            //actionGroupId: 'daoUniqueActionGroup',
            actionHandler: this.actionHandler,
            setToolbarState: (topToolBar, selectedIds) => {
                if (selectedIds.length > 0) {
                    //topToolBar.enable('setDaoUnique');
                }
                else {
                    //topToolBar.disable('setDaoUnique');
                }
            },
            onSelectChange:
                (selectRowKeys) => {
                    this.selectIds = selectRowKeys;
                }
            ,
        };

        return (
            <UIDataTableView {...tableProps} {...this.props}>
               
            </UIDataTableView>
        );
    }
}

/**
 * DAO 代码预览
 */
const ProductDaoObjectCodePreviewPanel = WarpModelObjectCodePreviewPanel({
    targetType : 'DAO',
});


/**
 * 数据表对象编辑Tab
 */
const DataTableObjectEditTabsPanel = WarpModelObjectEditTabPanel({
    modelObjectType : 'DB',
    tabConfigId: 'tableObjectTab',
    titleIcon: 'table',
    onTabChange: (tabName,modelObject) => {
        
        switch (tabName) {
            case 'basicInfo':
                this.tableFormRef.setModelObject(modelObject);
                break;
            case 'tableFieldList':
                this.tableFieldListRef.setModelObject(modelObject);
                break;
        }
    },
    getTabPanelMap: (warpedProps) => {
        return {
            '/productTableObjectFormPanel': {
                getComponent: (owner, props) => {
                    return (<ProductTableObjectFormPanel {...warpedProps} ref={(inst) => this.tableFormRef = inst} />);
                }
            },
            '/productTableFieldListPanel': {
                getComponent: (owner, props) => {
                    return (<ProductTableFieldListPanel {...warpedProps} ref={(inst) => this.tableFieldListRef = inst} />);
                }
            },
        }
    },
});

/** 
 * 表对象编辑表单
*/
const ProductTableObjectFormPanel = WarpModelObjectFormPanel({ formConfigId: 'productTableObjectForm' });

/** 
 * 表字段列表
*/
const ProductTableFieldListPanel = WarpModelPropertyListTabPanel({
    tableConfigId : 'tableObjectFieldList',
    actionGroupId : 'tableFieldListActionGroup',
    rowActionGroupId : 'tableFieldRowActionGroup',
    formConfigId : 'addNewProductDatabaseTableColumnForm',
});


class StartJobModal extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            selectModelObjects: [],
            domainId: -1,
        }
    }

    setParams = (params) => {
        this.setState(params);
    }

    onSelectModelPackage = (modelPackageId) => {
        this.setState({ selectedPackageId: modelPackageId });
        this.exportModal.getToolbar().enable('startJob');
        if (this.props.onSelectModelPackage) {
			this.props.onSelectModelPackage(modelPackageId);
		}
    }

    actionHandler = (actionEvent) => {

        const { exportModal } = this;

        return {
            doStartJob: () => {
                exportModal.closeModal();
                setTimeout(() => {
                    this.startJob.start();
                }, 0);
            }
        };
    }

    openModal = (params) => {
        this.setState(params);
        setTimeout(() => {
            this.exportModal.openModal();
        });
    }

    render() {

        const { jobTitle, packageType, startJobUrl, startJobParamData, checkJobUrl, checkJobParamData } = this.props;

        const { selectModelObjects, domainId,selectedPackageId } = this.state;

        const importViewProps = {
            ref: (inst) => { this.exportModal = inst },
            title: jobTitle,
            actionGroupId: 'startJobActionGroup',
            actionHandler: this.actionHandler,
            inPop: true,
            destroyOnClose: true,
            setToolbarState: (toolbar) => {
                toolbar.disable('startJob');
            },
        };

        const jobProps = {
            initValue: 0,
            checkInterval: 500,
            startJobUrl: startJobUrl,
            startJobParamData: {...startJobParamData,packageId : selectedPackageId},
            checkJobUrl: checkJobUrl,
            checkJobParamData: {...checkJobParamData,packageId : selectedPackageId},
            onJobFinish: (data) => {
                console.log(data);
                if (data.success) {
                    showResultMessage({
                        success: true,
                        message: '任务完成',
                    });
                }
                else {
                    showResultMessage({
                        success: false,
                        message: '任务错误:' + data.message,
                    });
                }
            }
        };

        return (
            <React.Fragment>
                <UIView {...importViewProps}>
                    <Row gutter={8}>
                        <Col span={24}>
                            <ProductModelPackageSelect domainId={domainId} packageType={packageType} onSelectModelPackage={this.onSelectModelPackage}></ProductModelPackageSelect>
                        </Col>
                        <Col span={24} style={{ marginTop: 8 }}>
                            <List
                                style={{ height: '300px', overflow: 'auto' }}
                                header={<div>已选模型对象</div>}
                                bordered
                                dataSource={selectModelObjects}
                                renderItem={this.props.renderItem != null && this.props.renderItem}
                            />
                        </Col>
                    </Row>
                </UIView>
                <StartJobModla {...jobProps} title="进度" ref={(inst) => { this.startJob = inst }} />
            </React.Fragment>
        );
    }
}
